<!DOCTYPE HTML>
<html lang="zh-cn" class="light" dir="ltr">
    <head>
            <script type="text/x-mathjax-config">
                MathJax.Hub.Config({
                    showProcessingMessages: false,
                    messageStyle: "none",
                    extensions: ['tex2jax.js'],
                    jax: ['input/TeX', 'output/HTML-CSS'],
                    tex2jax: {
                        inlineMath: [ ['$','$'], ["\\(","\\)"] ],
                        displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
                        processEscapes: true
                    },
                    "HTML-CSS": { availableFonts: ["STIX", "TeX"] }
                });
            </script>
            
        <!-- Book generated using mdBook -->
        <meta charset="UTF-8">
        <title>类 - 仓颉编程语言扩展库 API</title>


        <!-- Custom HTML head -->
        
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="theme-color" content="#ffffff">

        <link rel="icon" href="../../../favicon.svg">
        <link rel="shortcut icon" href="../../../favicon.png">
        <link rel="stylesheet" href="../../../css/variables.css">
        <link rel="stylesheet" href="../../../css/general.css">
        <link rel="stylesheet" href="../../../css/chrome.css">
        <link rel="stylesheet" href="../../../css/print.css" media="print">

        <!-- Fonts -->
        <link rel="stylesheet" href="../../../FontAwesome/css/font-awesome.css">
        <link rel="stylesheet" href="../../../fonts/fonts.css">

        <!-- Highlight.js Stylesheets -->
        <link rel="stylesheet" href="../../../highlight.css">
        <link rel="stylesheet" href="../../../tomorrow-night.css">
        <link rel="stylesheet" href="../../../ayu-highlight.css">

        <!-- Custom theme stylesheets -->
        <link rel="stylesheet" href="../../../assets/style.css">
        <link rel="stylesheet" href="../../../assets/theme.css">

        <!-- MathJax -->
        <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
    </head>
    <body class="sidebar-visible no-js">
    <div id="body-container">
        <!-- Provide site root to javascript -->
        <script>
            var path_to_root = "../../../";
            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
        </script>

        <!-- Work around some values being stored in localStorage wrapped in quotes -->
        <script>
            try {
                var theme = localStorage.getItem('mdbook-theme');
                var sidebar = localStorage.getItem('mdbook-sidebar');

                if (theme.startsWith('"') && theme.endsWith('"')) {
                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
                }

                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
                }
            } catch (e) { }
        </script>

        <!-- Set the theme before any content is loaded, prevents flash -->
        <script>
            var theme;
            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
            if (theme === null || theme === undefined) { theme = default_theme; }
            var html = document.querySelector('html');
            html.classList.remove('light')
            html.classList.add(theme);
            var body = document.querySelector('body');
            body.classList.remove('no-js')
            body.classList.add('js');
        </script>

        <input type="checkbox" id="sidebar-toggle-anchor" class="hidden">

        <!-- Hide / unhide sidebar before it is displayed -->
        <script>
            var body = document.querySelector('body');
            var sidebar = null;
            var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
            if (document.body.clientWidth >= 1080) {
                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
                sidebar = sidebar || 'visible';
            } else {
                sidebar = 'hidden';
            }
            sidebar_toggle.checked = sidebar === 'visible';
            body.classList.remove('sidebar-visible');
            body.classList.add("sidebar-" + sidebar);
        </script>

        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                <ol class="chapter"><li class="chapter-item expanded "><a href="../../../libs_overview.html"><strong aria-hidden="true">1.</strong> 仓颉编程语言扩展库 API</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../compress/zlib/zlib_package_overview.html"><strong aria-hidden="true">1.1.</strong> stdx.compress.zlib</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../compress/zlib/zlib_package_api/zlib_package_classes.html"><strong aria-hidden="true">1.1.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../compress/zlib/zlib_package_api/zlib_package_enums.html"><strong aria-hidden="true">1.1.2.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../compress/zlib/zlib_package_api/zlib_package_exceptions.html"><strong aria-hidden="true">1.1.3.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.1.4.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../compress/zlib/zlib_samples/deflate_compress_decompress.html"><strong aria-hidden="true">1.1.4.1.</strong> Deflate 格式数据的压缩和解压</a></li><li class="chapter-item "><a href="../../../compress/zlib/zlib_samples/gzip_compress_decompress.html"><strong aria-hidden="true">1.1.4.2.</strong> Gzip 格式数据的压缩和解压</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../crypto/crypto/crypto_package_overview.html"><strong aria-hidden="true">1.2.</strong> stdx.crypto.crypto</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/crypto/crypto_package_api/crypto_package_classes.html"><strong aria-hidden="true">1.2.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../crypto/crypto/crypto_package_api/crypto_package_structs.html"><strong aria-hidden="true">1.2.2.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../crypto/crypto/crypto_package_api/crypto_package_exceptions.html"><strong aria-hidden="true">1.2.3.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.2.4.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/crypto/crypto_samples/sample_secure_random.html"><strong aria-hidden="true">1.2.4.1.</strong> SecureRandom 使用</a></li><li class="chapter-item "><a href="../../../crypto/crypto/crypto_samples/sample_crypto.html"><strong aria-hidden="true">1.2.4.2.</strong> SM4 使用</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../crypto/digest/crypto_digest_package_overview.html"><strong aria-hidden="true">1.3.</strong> stdx.crypto.digest</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/digest/digest_package_api/digest_package_classes.html"><strong aria-hidden="true">1.3.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../crypto/digest/digest_package_api/digest_package_structs.html"><strong aria-hidden="true">1.3.2.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../crypto/digest/digest_package_api/digest_package_exceptions.html"><strong aria-hidden="true">1.3.3.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.3.4.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/digest/digest_samples/sample_digest.html"><strong aria-hidden="true">1.3.4.1.</strong> digest 使用</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../crypto/keys/keys_package_overview.html"><strong aria-hidden="true">1.4.</strong> stdx.crypto.keys</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/keys/keys_package_api/keys_package_classes.html"><strong aria-hidden="true">1.4.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../crypto/keys/keys_package_api/keys_package_enums.html"><strong aria-hidden="true">1.4.2.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../crypto/keys/keys_package_api/keys_package_structs.html"><strong aria-hidden="true">1.4.3.</strong> 结构体</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.4.4.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/keys/keys_samples/sample_keys.html"><strong aria-hidden="true">1.4.4.1.</strong> keys 使用</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_overview.html"><strong aria-hidden="true">1.5.</strong> stdx.crypto.x509</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_type.html"><strong aria-hidden="true">1.5.1.</strong> 类型别名</a></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_interfaces.html"><strong aria-hidden="true">1.5.2.</strong> 接口</a></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_classes.html"><strong aria-hidden="true">1.5.3.</strong> 类</a></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_enums.html"><strong aria-hidden="true">1.5.4.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_structs.html"><strong aria-hidden="true">1.5.5.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../crypto/x509/x509_package_api/x509_package_exceptions.html"><strong aria-hidden="true">1.5.6.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.5.7.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../crypto/x509/x509_samples/sample_x509.html"><strong aria-hidden="true">1.5.7.1.</strong> x509 使用</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../encoding/base64/base64_package_overview.html"><strong aria-hidden="true">1.6.</strong> stdx.encoding.base64</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/base64/base64_package_api/base64_package_funcs.html"><strong aria-hidden="true">1.6.1.</strong> 函数</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.6.2.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/base64/base64_samples/base64.html"><strong aria-hidden="true">1.6.2.1.</strong> Byte 数组和 Base64 互转</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../encoding/hex/hex_package_overview.html"><strong aria-hidden="true">1.7.</strong> stdx.encoding.hex</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/hex/hex_package_api/hex_package_funcs.html"><strong aria-hidden="true">1.7.1.</strong> 函数</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.7.2.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/hex/hex_samples/hex.html"><strong aria-hidden="true">1.7.2.1.</strong> Byte 数组和 Hex 互转</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../encoding/json/json_package_overview.html"><strong aria-hidden="true">1.8.</strong> stdx.encoding.json</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/json/json_package_api/encoding_json_package_interfaces.html"><strong aria-hidden="true">1.8.1.</strong> 接口</a></li><li class="chapter-item "><a href="../../../encoding/json/json_package_api/encoding_json_package_classes.html"><strong aria-hidden="true">1.8.2.</strong> 类</a></li><li class="chapter-item "><a href="../../../encoding/json/json_package_api/encoding_json_package_enums.html"><strong aria-hidden="true">1.8.3.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../encoding/json/json_package_api/encoding_json_package_exceptions.html"><strong aria-hidden="true">1.8.4.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.8.5.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/json/json_samples/json_array_sample.html"><strong aria-hidden="true">1.8.5.1.</strong> JsonArray 使用示例</a></li><li class="chapter-item "><a href="../../../encoding/json/json_samples/json_value_sample.html"><strong aria-hidden="true">1.8.5.2.</strong> JsonValue 和 String 互相转换</a></li><li class="chapter-item "><a href="../../../encoding/json/json_samples/to_json_sample.html"><strong aria-hidden="true">1.8.5.3.</strong> JsonValue 与 DataModel 的转换</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_package_overview.html"><strong aria-hidden="true">1.9.</strong> stdx.encoding.json.stream</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_package_api/encoding_json_stream_package_interfaces.html"><strong aria-hidden="true">1.9.1.</strong> 接口</a></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_package_api/encoding_json_stream_package_classes.html"><strong aria-hidden="true">1.9.2.</strong> 类</a></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_package_api/encoding_json_stream_package_enums.html"><strong aria-hidden="true">1.9.3.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_package_api/encoding_json_stream_package_structs.html"><strong aria-hidden="true">1.9.4.</strong> 结构体</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.9.5.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_samples/sample_json_reader.html"><strong aria-hidden="true">1.9.5.1.</strong> 使用 Json Stream 进行反序列化</a></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_samples/sample_json_writer.html"><strong aria-hidden="true">1.9.5.2.</strong> 使用 Json Stream 进行序列化</a></li><li class="chapter-item "><a href="../../../encoding/json_stream/json_stream_samples/sample_json_writeconfig.html"><strong aria-hidden="true">1.9.5.3.</strong> WriteConfig 使用示例</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../encoding/url/url_package_overview.html"><strong aria-hidden="true">1.10.</strong> stdx.encoding.url</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/url/url_package_api/url_package_classes.html"><strong aria-hidden="true">1.10.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../encoding/url/url_package_api/url_package_exceptions.html"><strong aria-hidden="true">1.10.2.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.10.3.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../encoding/url/url_samples/form.html"><strong aria-hidden="true">1.10.3.1.</strong> Form 的构造使用</a></li><li class="chapter-item "><a href="../../../encoding/url/url_samples/url_parse.html"><strong aria-hidden="true">1.10.3.2.</strong> URL 解析函数 parse 的使用</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../fuzz/fuzz_package_overview.html"><strong aria-hidden="true">1.11.</strong> stdx.fuzz.fuzz</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../fuzz/fuzz_package_api/fuzz_package_constants_vars.html"><strong aria-hidden="true">1.11.1.</strong> 常量变量</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_package_api/fuzz_package_classes.html"><strong aria-hidden="true">1.11.2.</strong> 类</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_package_api/fuzz_package_exceptions.html"><strong aria-hidden="true">1.11.3.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.11.4.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/basic_fuzzing_test.html"><strong aria-hidden="true">1.11.4.1.</strong> 测试猜测字符功能</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/dataprovider_usage.html"><strong aria-hidden="true">1.11.4.2.</strong> 使用 DataProvider 功能进行测试</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/fake_coverage_usage.html"><strong aria-hidden="true">1.11.4.3.</strong> 使用 FakeCoverage 避免 DataProvider 模式下 Fuzz 异常终止</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/print_cj-fuzz_usage.html"><strong aria-hidden="true">1.11.4.4.</strong> 打印 fuzz 使用方法</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/print_coverage.html"><strong aria-hidden="true">1.11.4.5.</strong> 实验性特性-覆盖率信息打印</a></li><li class="chapter-item "><a href="../../../fuzz/fuzz_samples/stack_backtrace_missing_solution.html"><strong aria-hidden="true">1.11.4.6.</strong> 栈回溯缺失的处理方案</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../log/log_package_overview.html"><strong aria-hidden="true">1.12.</strong> stdx.log</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../log/log_package_api/log_package_types.html"><strong aria-hidden="true">1.12.1.</strong> 类型别名</a></li><li class="chapter-item "><a href="../../../log/log_package_api/log_package_funcs.html"><strong aria-hidden="true">1.12.2.</strong> 函数</a></li><li class="chapter-item "><a href="../../../log/log_package_api/log_package_interfaces.html"><strong aria-hidden="true">1.12.3.</strong> 接口</a></li><li class="chapter-item "><a href="../../../log/log_package_api/log_package_classes.html"><strong aria-hidden="true">1.12.4.</strong> 类</a></li><li class="chapter-item "><a href="../../../log/log_package_api/log_package_structs.html"><strong aria-hidden="true">1.12.5.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../log/log_package_api/log_package_exceptions.html"><strong aria-hidden="true">1.12.6.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.12.7.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../log/log_samples/log_sample.html"><strong aria-hidden="true">1.12.7.1.</strong> 日志打印示例</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../logger/logger_package_overview.html"><strong aria-hidden="true">1.13.</strong> stdx.logger</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../logger/logger_package_api/logger_package_classes.html"><strong aria-hidden="true">1.13.1.</strong> 类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.13.2.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../logger/logger_samples/logger_sample.html"><strong aria-hidden="true">1.13.2.1.</strong> 日志打印示例</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../../../net/http/http_package_overview.html"><strong aria-hidden="true">1.14.</strong> stdx.net.http</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../net/http/http_package_api/http_package_funcs.html"><strong aria-hidden="true">1.14.1.</strong> 函数</a></li><li class="chapter-item "><a href="../../../net/http/http_package_api/http_package_interfaces.html"><strong aria-hidden="true">1.14.2.</strong> 接口</a></li><li class="chapter-item expanded "><a href="../../../net/http/http_package_api/http_package_classes.html" class="active"><strong aria-hidden="true">1.14.3.</strong> 类</a></li><li class="chapter-item "><a href="../../../net/http/http_package_api/http_package_enums.html"><strong aria-hidden="true">1.14.4.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../net/http/http_package_api/http_package_structs.html"><strong aria-hidden="true">1.14.5.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../net/http/http_package_api/http_package_exceptions.html"><strong aria-hidden="true">1.14.6.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.14.7.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../net/http/http_samples/http_client.html"><strong aria-hidden="true">1.14.7.1.</strong> client</a></li><li class="chapter-item "><a href="../../../net/http/http_samples/cookie.html"><strong aria-hidden="true">1.14.7.2.</strong> cookie</a></li><li class="chapter-item "><a href="../../../net/http/http_samples/log.html"><strong aria-hidden="true">1.14.7.3.</strong> log</a></li><li class="chapter-item "><a href="../../../net/http/http_samples/http_server.html"><strong aria-hidden="true">1.14.7.4.</strong> server</a></li><li class="chapter-item "><a href="../../../net/http/http_samples/webSocket.html"><strong aria-hidden="true">1.14.7.5.</strong> webSocket</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../net/tls/tls_package_overview.html"><strong aria-hidden="true">1.15.</strong> stdx.net.tls</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../net/tls/tls_package_api/tls_package_classes.html"><strong aria-hidden="true">1.15.1.</strong> 类</a></li><li class="chapter-item "><a href="../../../net/tls/tls_package_api/tls_package_enums.html"><strong aria-hidden="true">1.15.2.</strong> 枚举</a></li><li class="chapter-item "><a href="../../../net/tls/tls_package_api/tls_package_structs.html"><strong aria-hidden="true">1.15.3.</strong> 结构体</a></li><li class="chapter-item "><a href="../../../net/tls/tls_package_api/tls_package_exceptions.html"><strong aria-hidden="true">1.15.4.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.15.5.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../net/tls/tls_samples/cert_key.html"><strong aria-hidden="true">1.15.5.1.</strong> 服务端证书及公钥在一份文件中</a></li><li class="chapter-item "><a href="../../../net/tls/tls_samples/client.html"><strong aria-hidden="true">1.15.5.2.</strong> 客户端示例</a></li><li class="chapter-item "><a href="../../../net/tls/tls_samples/hot_update_cert.html"><strong aria-hidden="true">1.15.5.3.</strong> 证书热更新</a></li><li class="chapter-item "><a href="../../../net/tls/tls_samples/server.html"><strong aria-hidden="true">1.15.5.4.</strong> 服务端示例</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../serialization/serialization_package_overview.html"><strong aria-hidden="true">1.16.</strong> stdx.serialization.serialization</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../serialization/serialization_package_api/serialization_package_functions.html"><strong aria-hidden="true">1.16.1.</strong> 函数</a></li><li class="chapter-item "><a href="../../../serialization/serialization_package_api/serialization_package_interfaces.html"><strong aria-hidden="true">1.16.2.</strong> 接口</a></li><li class="chapter-item "><a href="../../../serialization/serialization_package_api/serialization_package_classes.html"><strong aria-hidden="true">1.16.3.</strong> 类</a></li><li class="chapter-item "><a href="../../../serialization/serialization_package_api/serialization_package_exceptions.html"><strong aria-hidden="true">1.16.4.</strong> 异常类</a></li><li class="chapter-item "><div><strong aria-hidden="true">1.16.5.</strong> 示例教程</div><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../serialization/serialization_samples/serialize_and_deserialize_class.html"><strong aria-hidden="true">1.16.5.1.</strong> class 序列化和反序列化</a></li><li class="chapter-item "><a href="../../../serialization/serialization_samples/serialize_hashmap_and_hashset.html"><strong aria-hidden="true">1.16.5.2.</strong> HashSet 和 HashMap 序列化</a></li></ol></li></ol></li><li class="chapter-item "><a href="../../../unittest/data/data_package_overview.html"><strong aria-hidden="true">1.17.</strong> stdx.unittest.data</a><a class="toggle"><div>❱</div></a></li><li><ol class="section"><li class="chapter-item "><a href="../../../unittest/data/data_package_api/data_package_functions.html"><strong aria-hidden="true">1.17.1.</strong> 函数</a></li><li class="chapter-item "><a href="../../../unittest/data/data_package_api/data_package_classes.html"><strong aria-hidden="true">1.17.2.</strong> 类</a></li></ol></li></ol></li></ol>
            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle">
                <div class="sidebar-resize-indicator"></div>
            </div>
        </nav>

        <!-- Track and set sidebar scroll position -->
        <script>
            var sidebarScrollbox = document.querySelector('#sidebar .sidebar-scrollbox');
            sidebarScrollbox.addEventListener('click', function(e) {
                if (e.target.tagName === 'A') {
                    sessionStorage.setItem('sidebar-scroll', sidebarScrollbox.scrollTop);
                }
            }, { passive: true });
            var sidebarScrollTop = sessionStorage.getItem('sidebar-scroll');
            sessionStorage.removeItem('sidebar-scroll');
            if (sidebarScrollTop) {
                // preserve sidebar scroll position when navigating via links within sidebar
                sidebarScrollbox.scrollTop = sidebarScrollTop;
            } else {
                // scroll sidebar to current active section when navigating via "next/previous chapter" buttons
                var activeSection = document.querySelector('#sidebar .active');
                if (activeSection) {
                    activeSection.scrollIntoView({ block: 'center' });
                }
            }
        </script>

        <div id="page-wrapper" class="page-wrapper">

            <div class="page">
                                <div id="menu-bar-hover-placeholder"></div>
                <div id="menu-bar" class="menu-bar sticky">
                    <div class="left-buttons">
                        <label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
                            <i class="fa fa-bars"></i>
                        </label>
                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
                            <i class="fa fa-paint-brush"></i>
                        </button>
                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
                            <li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
                            <li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
                        </ul>
                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
                            <i class="fa fa-search"></i>
                        </button>
                    </div>

                    <h1 class="menu-title">仓颉编程语言扩展库 API</h1>

                    <div class="right-buttons">
                        <a href="../../../print.html" title="Print this book" aria-label="Print this book">
                            <i id="print-button" class="fa fa-print"></i>
                        </a>

                    </div>
                </div>

                <div id="search-wrapper" class="hidden">
                    <form id="searchbar-outer" class="searchbar-outer">
                        <input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
                    </form>
                    <div id="searchresults-outer" class="searchresults-outer hidden">
                        <div id="searchresults-header" class="searchresults-header"></div>
                        <ul id="searchresults">
                        </ul>
                    </div>
                </div>

                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
                <script>
                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
                    });
                </script>

                <div id="content" class="content">
                    <main>
                        <h1 id="类"><a class="header" href="#类">类</a></h1>
<h2 id="class-client"><a class="header" href="#class-client">class Client</a></h2>
<pre><code class="language-cangjie">public class Client
</code></pre>
<p>功能：发送 Http request、随时关闭等。用户可以通过 Client 实例发送 HTTP/1.1 或 HTTP/2 请求。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p><a href="http_package_classes.html#class-client">Client</a> 文档中未明确说明支持版本的配置，在 HTTP/1.1 与 HTTP/2 都会生效。</p>
</blockquote>
<h3 id="prop-autoredirect"><a class="header" href="#prop-autoredirect">prop autoRedirect</a></h3>
<pre><code class="language-cangjie">public prop autoRedirect: Bool
</code></pre>
<p>功能：客户端是否会自动进行重定向，304 状态码默认不重定向。</p>
<p>类型：Bool</p>
<h3 id="prop-connector"><a class="header" href="#prop-connector">prop connector</a></h3>
<pre><code class="language-cangjie">public prop connector: (SocketAddress) -&gt; StreamingSocket
</code></pre>
<p>功能：客户端调用此函数获取到服务器的连接。</p>
<p>类型：(SocketAddress) -&gt; StreamingSocket</p>
<h3 id="prop-cookiejar"><a class="header" href="#prop-cookiejar">prop cookieJar</a></h3>
<pre><code class="language-cangjie">public prop cookieJar: ?CookieJar
</code></pre>
<p>功能：用于存储客户端所有 <a href="http_package_classes.html#class-cookie">Cookie</a>，如果配置为 None，则不会启用 <a href="http_package_classes.html#class-cookie">Cookie</a>。</p>
<p>类型：?<a href="http_package_interfaces.html#interface-cookiejar">CookieJar</a></p>
<h3 id="prop-enablepush"><a class="header" href="#prop-enablepush">prop enablePush</a></h3>
<pre><code class="language-cangjie">public prop enablePush: Bool
</code></pre>
<p>功能：客户端 HTTP/2 是否支持服务器推送，默认值为 true。</p>
<p>类型：Bool</p>
<h3 id="prop-headertablesize"><a class="header" href="#prop-headertablesize">prop headerTableSize</a></h3>
<pre><code class="language-cangjie">public prop headerTableSize: UInt32
</code></pre>
<p>功能：获取客户端 HTTP/2 Hpack 动态表的初始值，默认值为 4096。</p>
<p>类型：UInt32</p>
<h3 id="prop-httpproxy"><a class="header" href="#prop-httpproxy">prop httpProxy</a></h3>
<pre><code class="language-cangjie">public prop httpProxy: String
</code></pre>
<p>功能：获取客户端 http 代理，默认使用系统环境变量 http_proxy 的值，用字符串表示，格式为：<code>&quot;http://host:port&quot;</code>，例如：<code>&quot;http://192.168.1.1:80&quot;</code>。</p>
<p>类型：String</p>
<h3 id="prop-httpsproxy"><a class="header" href="#prop-httpsproxy">prop httpsProxy</a></h3>
<pre><code class="language-cangjie">public prop httpsProxy: String
</code></pre>
<p>功能：获取客户端 https 代理，默认使用系统环境变量 https_proxy 的值，用字符串表示，格式为：<code>&quot;http://host:port&quot;</code>，例如：<code>&quot;http://192.168.1.1:443&quot;</code>。</p>
<p>类型：String</p>
<h3 id="prop-initialwindowsize"><a class="header" href="#prop-initialwindowsize">prop initialWindowSize</a></h3>
<pre><code class="language-cangjie">public prop initialWindowSize: UInt32
</code></pre>
<p>功能：获取客户端 HTTP/2 流控窗口初始值，默认值为 65535 ，取值范围为 0 至 2^31 - 1。</p>
<p>类型：UInt32</p>
<h3 id="prop-logger"><a class="header" href="#prop-logger">prop logger</a></h3>
<pre><code class="language-cangjie">public prop logger: Logger
</code></pre>
<p>功能：获取客户端日志记录器，设置 logger.level 将立即生效，记录器应该是线程安全的。</p>
<p>类型：<a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a></p>
<h3 id="prop-maxconcurrentstreams"><a class="header" href="#prop-maxconcurrentstreams">prop maxConcurrentStreams</a></h3>
<pre><code class="language-cangjie">public prop maxConcurrentStreams: UInt32
</code></pre>
<p>功能：获取客户端 HTTP/2 初始最大并发流数量，默认值为 2^31 - 1。</p>
<p>类型：UInt32</p>
<h3 id="prop-maxframesize"><a class="header" href="#prop-maxframesize">prop maxFrameSize</a></h3>
<pre><code class="language-cangjie">public prop maxFrameSize: UInt32
</code></pre>
<p>功能：获取客户端 HTTP/2 初始最大帧大小。默认值为 16384. 取值范围为 2^14 至 2^24 - 1。</p>
<p>类型：UInt32</p>
<h3 id="prop-maxheaderlistsize"><a class="header" href="#prop-maxheaderlistsize">prop maxHeaderListSize</a></h3>
<pre><code class="language-cangjie">public prop maxHeaderListSize: UInt32
</code></pre>
<p>功能：获取客户端支持的 HTTP/2 最大头部（Header）大小。这个大小指的是响应头部中所有头部字段（Header Field）的最大允许长度之和，其中包括所有字段名称（name）的长度、字段值（value）的长度以及每个字段自动添加的伪头开销（通常每个字段会有32字节的开销，这包括了 HTTP/2 协议本身为头部字段添加的伪头部信息）。默认情况下，这个最大长度被设置为 UInt32.Max。</p>
<p>类型：UInt32</p>
<h3 id="prop-poolsize"><a class="header" href="#prop-poolsize">prop poolSize</a></h3>
<pre><code class="language-cangjie">public prop poolSize: Int64
</code></pre>
<p>功能：配置 HTTP/1.1 客户端使用的连接池的大小，亦可表示对同一个主机（host:port）同时存在的连接数的最大值。</p>
<p>类型：Int64</p>
<h3 id="prop-readtimeout"><a class="header" href="#prop-readtimeout">prop readTimeout</a></h3>
<pre><code class="language-cangjie">public prop readTimeout: Duration
</code></pre>
<p>功能：获取客户端设定的读取整个响应的超时时间，默认值为 15 秒。</p>
<p>类型：Duration</p>
<h3 id="prop-writetimeout"><a class="header" href="#prop-writetimeout">prop writeTimeout</a></h3>
<pre><code class="language-cangjie">public prop writeTimeout: Duration
</code></pre>
<p>功能：获取客户端设定的写请求的超时时间，默认值为 15 秒。</p>
<p>类型：Duration</p>
<h3 id="func-close"><a class="header" href="#func-close">func close()</a></h3>
<pre><code class="language-cangjie">public func close(): Unit
</code></pre>
<p>功能：关闭客户端建立的所有连接，调用后不能继续发送请求。</p>
<h3 id="func-connectstring-httpheaders-protocol"><a class="header" href="#func-connectstring-httpheaders-protocol">func connect(String, HttpHeaders, Protocol)</a></h3>
<pre><code class="language-cangjie">public func connect(url: String, header!: HttpHeaders = HttpHeaders(), version!: Protocol = HTTP1_1): (HttpResponse, ?StreamingSocket)
</code></pre>
<p>功能：发送 CONNECT 请求与服务器建立隧道，返回建连成功后的连接，连接由用户负责关闭。服务器返回 2xx 表示建连成功，否则建连失败（不支持自动重定向，3xx 也视为失败）。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>header!: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 请求头，默认为空请求头。</li>
<li>version!: <a href="http_package_enums.html#enum-protocol">Protocol</a> - 请求的协议，默认为 <a href="./http_package_enums.html#enum-Protocol">HTTP1_1</a>。</li>
</ul>
<p>返回值：</p>
<ul>
<li>(<a href="http_package_classes.html#class-httpresponse">HttpResponse</a>, ?StreamingSocket) - 返回元组类型，其中 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a> 实例表示服务器返回的响应体，Option&lt;StreamingSocket&gt; 实例表示请求成功时返回 headers 之后连接。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-deletestring"><a class="header" href="#func-deletestring">func delete(String)</a></h3>
<pre><code class="language-cangjie">public func delete(url: String): HttpResponse
</code></pre>
<p>功能：请求方法为 DELETE 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-getstring"><a class="header" href="#func-getstring">func get(String)</a></h3>
<pre><code class="language-cangjie">public func get(url: String): HttpResponse
</code></pre>
<p>功能：请求方法为 GET 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-gettlsconfig"><a class="header" href="#func-gettlsconfig">func getTlsConfig()</a></h3>
<pre><code class="language-cangjie">public func getTlsConfig(): ?TlsClientConfig
</code></pre>
<p>功能：获取客户端设定的 TLS 层配置。</p>
<p>返回值：</p>
<ul>
<li>?<a href="../../tls/tls_package_api/tls_package_structs.html#struct-tlsclientconfig">TlsClientConfig</a> - 客户端设定的 TLS 层配置，如果没有设置则返回 None。</li>
</ul>
<h3 id="func-headstring"><a class="header" href="#func-headstring">func head(String)</a></h3>
<pre><code class="language-cangjie">public func head(url: String): HttpResponse
</code></pre>
<p>功能：请求方法为 HEAD 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-optionsstring"><a class="header" href="#func-optionsstring">func options(String)</a></h3>
<pre><code class="language-cangjie">public func options(url: String): HttpResponse
</code></pre>
<p>功能：请求方法为 OPTIONS 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-poststring-arrayuint8"><a class="header" href="#func-poststring-arrayuint8">func post(String, Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func post(url: String, body: Array&lt;UInt8&gt;): HttpResponse
</code></pre>
<p>功能：请求方法为 POST 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: Array&lt;UInt8&gt; - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-poststring-inputstream"><a class="header" href="#func-poststring-inputstream">func post(String, InputStream)</a></h3>
<pre><code class="language-cangjie">public func post(url: String, body: InputStream): HttpResponse
</code></pre>
<p>功能：请求方法为 POST 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: InputStream - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-poststring-string"><a class="header" href="#func-poststring-string">func post(String, String)</a></h3>
<pre><code class="language-cangjie">public func post(url: String, body: String): HttpResponse
</code></pre>
<p>功能：请求方法为 POST 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: String - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-putstring-arrayuint8"><a class="header" href="#func-putstring-arrayuint8">func put(String, Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func put(url: String, body: Array&lt;UInt8&gt;): HttpResponse
</code></pre>
<p>功能：请求方法为 PUT 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: Array&lt;UInt8&gt; - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-putstring-inputstream"><a class="header" href="#func-putstring-inputstream">func put(String, InputStream)</a></h3>
<pre><code class="language-cangjie">public func put(url: String, body: InputStream): HttpResponse
</code></pre>
<p>功能：请求方法为 PUT 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: InputStream - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-putstring-string"><a class="header" href="#func-putstring-string">func put(String, String)</a></h3>
<pre><code class="language-cangjie">public func put(url: String, body: String): HttpResponse
</code></pre>
<p>功能：请求方法为 PUT 的便捷请求函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 请求的 url。</li>
<li>body: String - 请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当参数 url 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 解析规范时，抛出异常。</li>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF-8 的字节序列规则时，抛出异常。</li>
<li>其余同 func send。</li>
</ul>
<h3 id="func-sendhttprequest"><a class="header" href="#func-sendhttprequest">func send(HttpRequest)</a></h3>
<pre><code class="language-cangjie">public func send(req: HttpRequest): HttpResponse
</code></pre>
<p>功能：通用请求函数，发送 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 到 url 中的服务器，接收 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a>。</p>
<blockquote>
<p><strong>注意:</strong></p>
<ul>
<li>对于 HTTP/1.1，如果请求中有 body 要发，那么需要保证 Content-Length 和 Transfer-Encoding: chunked 必有且只有一个，以 chunked 形式发时，每段 chunk 最大为 8192 字节；如果用户发送的 body 为自己实现的 InputStream 类，则需要自己保证 Content-Length和 Transfer-Encoding: chunked 设置且只设置了一个；如果用户采用默认的 body 发送，Content-Length 和 Transfer-Encoding: chunked 都缺失时，我们会为其补上 Content-Length header，值为 body.size；</li>
<li>用户如果设置了 Content-Length，则需要保证其正确性：如果所发 body 的内容大于等于 Content-Length 的值，我们会发送长度为 Content-Length 值的数据；如果所发 body 的内容小于 Content-Length 的值，此时如果 body 是默认的 body，则会抛出 <a href="http_package_exceptions.html#class-httpexception">HttpException</a>，如果 body是用户自己实现的 InputStream 类，其行为便无法保证（可能会造成服务器端的读 request 超时或者客户端的收 response 超时）；</li>
<li>升级函数通过 <a href="http_package_classes.html#class-websocket">WebSocket</a> 的 upgradeFromClient 或 <a href="http_package_classes.html#class-client">Client</a> 的 <a href="http_package_funcs.html#func-upgradehttpcontext">upgrade</a> 接口发出，调用 client 的其他函数发送 <a href="http_package_funcs.html#func-upgradehttpcontext">upgrade</a> 请求会抛出异常；</li>
<li>协议规定 TRACE 请求无法携带内容，故用户发送带有 body 的 TRACE 请求时会抛出异常；</li>
<li>HTTP/1.1 默认对同一个服务器的连接数不超过 10 个。response 的 body 需要用户调用 <code>body.read(buf: Array&lt;Byte&gt;)</code> 函数去读。body 被读完后，连接才能被客户端对象复用，否则请求相同的服务器也会新建连接。新建连接时如果连接数超出限制则会抛出 <a href="http_package_exceptions.html#class-httpexception">HttpException</a>；</li>
<li>body.read 函数将 body 读完之后返回 0，如果读的时候连接断开会抛出 <a href="http_package_exceptions.html#class-connectionexception">ConnectionException</a>；</li>
<li>HTTP/1.1 的升级请求如果收到 101 响应，则表示切换协议，此连接便不归 client 管理；</li>
<li>下文的快捷请求函数的注意点与 send 相同。</li>
</ul>
</blockquote>
<p>参数：</p>
<ul>
<li>req: <a href="http_package_classes.html#class-httprequest">HttpRequest</a> - 发送的请求。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 服务端返回处理该请求的响应。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 请求中 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 错误时抛此异常。</li>
<li>SocketException - Socket 连接出现错误时抛此异常。</li>
<li><a href="http_package_exceptions.html#class-connectionexception">ConnectionException</a> - 从连接中读数据时对端已关闭连接抛此异常。</li>
<li>SocketTimeoutException - Socket 连接超时抛此异常。</li>
<li><a href="../../tls/tls_package_api/tls_package_exceptions.html#class-tlsexception">TlsException</a> - Tls 连接建立失败或通信异常抛此异常。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 当用户未使用 http 库提供的 API 升级 <a href="http_package_classes.html#class-websocket">WebSocket</a> 时抛此异常。</li>
<li><a href="http_package_exceptions.html#class-httptimeoutexception">HttpTimeoutException</a> - 请求超时或读 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a>.body 超时抛此异常。</li>
</ul>
<h3 id="func-upgradehttprequest"><a class="header" href="#func-upgradehttprequest">func upgrade(HttpRequest)</a></h3>
<pre><code class="language-cangjie">public func upgrade(req: HttpRequest): (HttpResponse, ?StreamingSocket)
</code></pre>
<p>功能：发送请求并升级协议，用户设置请求头，返回升级后的连接（如果升级成功），连接由用户负责关闭。</p>
<blockquote>
<p><strong>说明：</strong></p>
<ul>
<li>服务器返回 101 表示升级成功，获取到了 StreamingSocket；</li>
<li>必选请求头:
<ul>
<li>Upgrade:  protocol-name [&quot;/&quot; protocol-version]；</li>
<li>Connection: Upgrade (在请求头包含 Upgrade 字段时会自动添加)；</li>
</ul>
</li>
<li>不支持 HTTP/1.0、HTTP/2；</li>
<li>不支持 HTTP/1.1 CONNECT 方法的 <a href="http_package_classes.html#class-httprequest">HttpRequest</a>。</li>
</ul>
</blockquote>
<p>参数：</p>
<ul>
<li>req: <a href="http_package_classes.html#class-httprequest">HttpRequest</a> - 升级时发送的请求。</li>
</ul>
<p>返回值：</p>
<ul>
<li>(<a href="http_package_classes.html#class-httpresponse">HttpResponse</a>,?StreamingSocket) - 返回一个元组，<a href="http_package_classes.html#class-httpresponse">HttpResponse</a> 实例表示服务器返回的响应，?StreamingSocket 实例表示获取的底层连接，升级失败时为 None。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> -
<ul>
<li>请求报文或响应报文不符合协议；</li>
<li>请求报文不含 Upgrade 头；</li>
<li>发送 CONNECT 请求；</li>
<li>发送带 body 的 TRACE 请求；</li>
</ul>
</li>
<li>SocketException，<a href="http_package_exceptions.html#class-connectionexception">ConnectionException</a> - Socket 连接出现异常或被关闭；</li>
<li>SocketTimeoutException - Socket 连接超时；</li>
<li><a href="../../tls/tls_package_api/tls_package_exceptions.html#class-tlsexception">TlsException</a> - Tls 连接建立失败或通信异常。</li>
</ul>
<h2 id="class-clientbuilder"><a class="header" href="#class-clientbuilder">class ClientBuilder</a></h2>
<pre><code class="language-cangjie">public class ClientBuilder {
    public init()
}
</code></pre>
<p>功能：用于 <a href="http_package_classes.html#class-client">Client</a> 实例的构建，<a href="http_package_classes.html#class-client">Client</a> 没有公开的构造函数，用户只能通过 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 得到 <a href="http_package_classes.html#class-client">Client</a> 实例。<a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 文档中未明确说明支持版本的配置，在 HTTP/1.1 与 HTTP/2 都会生效。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>该类提供了一系列配置参数的函数，配置完成后调用 <a href="./http_package_classes.html#func-build">build</a> 函数构造出 <a href="./http_package_classes.html#class-client">Client</a> 实例。配置函数中说明了参数的取值范围，但配置函数本身不做参数合法性校验，<a href="./http_package_classes.html#func-build">build</a> 时统一进行校验。</p>
</blockquote>
<h3 id="init"><a class="header" href="#init">init()</a></h3>
<pre><code class="language-cangjie">public init()
</code></pre>
<p>功能：创建新的 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例。</p>
<h3 id="func-autoredirectbool"><a class="header" href="#func-autoredirectbool">func autoRedirect(Bool)</a></h3>
<pre><code class="language-cangjie">public func autoRedirect(auto: Bool): ClientBuilder
</code></pre>
<p>功能：配置客户端是否会自动进行重定向。重定向会请求 Location 头的资源，协议规定，Location 只能包含一个 URI 引用Location = URI-reference，详见 <a href="https://httpwg.org/specs/rfc9110.html#rfc.section.10.2.2">RFC 9110 10.2.2.</a>。304 状态码默认不重定向。</p>
<p>参数：</p>
<ul>
<li>auto: Bool - 默认值为 true，即开启自动重定向。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-build"><a class="header" href="#func-build">func build()</a></h3>
<pre><code class="language-cangjie">public func build(): Client
</code></pre>
<p>功能：构造 <a href="http_package_classes.html#class-client">Client</a> 实例。</p>
<p>此处会对各参数的值进行检查，如果取值非法，将抛出异常。各参数的取值范围详见设置参数相关的函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-client">Client</a> - 用当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例中的配置构建的 <a href="http_package_classes.html#class-client">Client</a> 实例。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 配置项有非法参数时抛出此异常。</li>
</ul>
<h3 id="func-connectorsocketaddress-streamingsocket"><a class="header" href="#func-connectorsocketaddress-streamingsocket">func connector((SocketAddress)-&gt;StreamingSocket)</a></h3>
<pre><code class="language-cangjie">public func connector(c: (SocketAddress) -&gt; StreamingSocket): ClientBuilder
</code></pre>
<p>功能：客户端调用此函数获取到服务器的连接。</p>
<p>参数：</p>
<ul>
<li>c: (SocketAddress) -&gt;StreamingSocket - 入参为 SocketAddress 实例，返回值类型为 StreamingSocket 的函数类型。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-cookiejarcookiejar"><a class="header" href="#func-cookiejarcookiejar">func cookieJar(?CookieJar)</a></h3>
<pre><code class="language-cangjie">public func cookieJar(cookieJar: ?CookieJar): ClientBuilder
</code></pre>
<p>功能：用于存储客户端所有 <a href="http_package_classes.html#class-cookie">Cookie</a>。</p>
<p>参数：</p>
<ul>
<li>cookieJar: ?<a href="http_package_interfaces.html#interface-cookiejar">CookieJar</a> - 默认使用一个空的 <a href="http_package_interfaces.html#interface-cookiejar">CookieJar</a>，如果配置为 None 则不会启用 <a href="http_package_classes.html#class-cookie">Cookie</a>。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-enablepushbool"><a class="header" href="#func-enablepushbool">func enablePush(Bool)</a></h3>
<pre><code class="language-cangjie">public func enablePush(enable: Bool): ClientBuilder
</code></pre>
<p>功能：配置客户端 HTTP/2 是否支持服务器推送。</p>
<p>参数：</p>
<ul>
<li>enable: Bool - 默认值 true。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-headertablesizeuint32"><a class="header" href="#func-headertablesizeuint32">func headerTableSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func headerTableSize(size: UInt32): ClientBuilder
</code></pre>
<p>功能：配置客户端 HTTP/2 Hpack 动态表初始值。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 默认值 4096。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-httpproxystring"><a class="header" href="#func-httpproxystring">func httpProxy(String)</a></h3>
<pre><code class="language-cangjie">public func httpProxy(addr: String): ClientBuilder
</code></pre>
<p>功能：设置客户端 http 代理，默认使用系统环境变量 http_proxy 的值。</p>
<p>参数：</p>
<ul>
<li>addr: String - 格式为：<code>&quot;http://host:port&quot;</code>，例如：<code>&quot;http://192.168.1.1:80&quot;</code>。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-httpsproxystring"><a class="header" href="#func-httpsproxystring">func httpsProxy(String)</a></h3>
<pre><code class="language-cangjie">public func httpsProxy(addr: String): ClientBuilder
</code></pre>
<p>功能：设置客户端 https 代理，默认使用系统环境变量 https_proxy 的值。</p>
<p>参数：</p>
<ul>
<li>addr: String - 格式为：<code>&quot;http://host:port&quot;</code>，例如：<code>&quot;http://192.168.1.1:443&quot;</code>。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-initialwindowsizeuint32"><a class="header" href="#func-initialwindowsizeuint32">func initialWindowSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func initialWindowSize(size: UInt32): ClientBuilder
</code></pre>
<p>功能：配置客户端 HTTP/2 流控窗口初始值。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 默认值 65535 ， 取值范围为 0 至 2^31 - 1。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-loggerlogger"><a class="header" href="#func-loggerlogger">func logger(Logger)</a></h3>
<pre><code class="language-cangjie">public func logger(logger: Logger): ClientBuilder
</code></pre>
<p>功能：设定客户端的 logger，默认 logger 级别为 INFO，logger 内容将写入 Console.stdout。</p>
<p>参数：</p>
<ul>
<li>logger: <a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a> - 需要是线程安全的，默认使用内置线程安全 logger。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-maxconcurrentstreamsuint32"><a class="header" href="#func-maxconcurrentstreamsuint32">func maxConcurrentStreams(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxConcurrentStreams(size: UInt32): ClientBuilder
</code></pre>
<p>功能：配置客户端 HTTP/2 初始最大并发流数量。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 默认值为 2^31 - 1。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-maxframesizeuint32"><a class="header" href="#func-maxframesizeuint32">func maxFrameSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxFrameSize(size: UInt32): ClientBuilder
</code></pre>
<p>功能：配置客户端 HTTP/2 初始最大帧大小。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 默认值为 16384。取值范围为 2^14 至 2^24 - 1。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-maxheaderlistsizeuint32"><a class="header" href="#func-maxheaderlistsizeuint32">func maxHeaderListSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxHeaderListSize(size: UInt32): ClientBuilder
</code></pre>
<p>功能：获取客户端支持的 HTTP/2 最大头部（Header）大小。这个大小指的是响应头部中所有头部字段（Header Field）的最大允许长度之和，其中包括所有字段名称（name）的长度、字段值（value）的长度以及每个字段自动添加的伪头开销（通常每个字段会有 32 字节的开销，这包括了 HTTP/2 协议本身为头部字段添加的伪头部信息）。默认情况下，这个最大长度被设置为 UInt32.Max。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 客户端接收的 HTTP/2 响应 headers 最大长度。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-noproxy"><a class="header" href="#func-noproxy">func noProxy()</a></h3>
<pre><code class="language-cangjie">public func noProxy(): ClientBuilder
</code></pre>
<p>功能：调用此函数后，客户端不使用任何代理。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-poolsizeint64"><a class="header" href="#func-poolsizeint64">func poolSize(Int64)</a></h3>
<pre><code class="language-cangjie">public func poolSize(size: Int64): ClientBuilder
</code></pre>
<p>功能：配置 HTTP/1.1 客户端使用的连接池的大小，亦可表示对同一个主机（host:port）同时存在的连接数的最大值。</p>
<p>参数：</p>
<ul>
<li>size: Int64 - 默认 10，poolSize 需要大于 0。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传参小于等于 0，则会抛出该异常。</li>
</ul>
<h3 id="func-readtimeoutduration"><a class="header" href="#func-readtimeoutduration">func readTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func readTimeout(timeout: Duration): ClientBuilder
</code></pre>
<p>功能：设定客户端读取一个响应的最大时长。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 默认 15s，Duration.Max 代表不限制，如果传入负的 Duration 将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-tlsconfigtlsclientconfig"><a class="header" href="#func-tlsconfigtlsclientconfig">func tlsConfig(TlsClientConfig)</a></h3>
<pre><code class="language-cangjie">public func tlsConfig(config: TlsClientConfig): ClientBuilder
</code></pre>
<p>功能：设置 TLS 层配置，默认不对其进行设置。</p>
<p>参数：</p>
<ul>
<li>config: <a href="../../tls/tls_package_api/tls_package_structs.html#struct-tlsclientconfig">TlsClientConfig</a> - 设定支持 tls 客户端需要的配置信息。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-writetimeoutduration"><a class="header" href="#func-writetimeoutduration">func writeTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func writeTimeout(timeout: Duration): ClientBuilder
</code></pre>
<p>功能：设定客户端发送一个请求的最大时长。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 默认 15 秒，Duration.Max 代表不限制，如果传入负的 Duration 将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> - 当前 <a href="http_package_classes.html#class-clientbuilder">ClientBuilder</a> 实例的引用。</li>
</ul>
<h2 id="class-cookie"><a class="header" href="#class-cookie">class Cookie</a></h2>
<pre><code class="language-cangjie">public class Cookie {
    public init(name: String, value: String, expires!: ?DateTime = None, maxAge!: ?Int64 = None,
        domain!: String = &quot;&quot;, path!: String = &quot;&quot;, secure!: Bool = false, httpOnly!: Bool = false)
}
</code></pre>
<p>功能：HTTP 本身是无状态的，server 为了知道 client 的状态，提供个性化的服务，便可以通过 <a href="http_package_classes.html#class-cookie">Cookie</a> 来维护一个有状态的会话。</p>
<blockquote>
<p><strong>说明：</strong></p>
<ul>
<li>用户首次访问某站点时，server 通过 <code>Set-Cookie</code> header 将 name/value 对，以及 attribute-value 传给用户代理；用户代理随后对该站点的请求中便可以将 name/value 加入到 Cookie header 中；</li>
<li><a href="http_package_classes.html#class-cookie">Cookie</a> 类提供了构建 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象，并将 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象转成 <code>Set-Cookie</code> header 值的函数，提供了获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象各属性值的函数；</li>
<li><a href="http_package_classes.html#class-cookie">Cookie</a> 的各个属性的要求和作用见 <a href="https://httpwg.org/specs/rfc6265.html">RFC 6265</a>；</li>
<li>下文中 cookie-name，cookie-value，expires-av 等名字采用 <a href="https://httpwg.org/specs/rfc6265.html">RFC 6265</a> 中的术语，详情请见协议。</li>
</ul>
</blockquote>
<h3 id="prop-cookiename"><a class="header" href="#prop-cookiename">prop cookieName</a></h3>
<pre><code class="language-cangjie">public prop cookieName: String
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 cookie-name 值。</p>
<p>类型：String</p>
<h3 id="prop-cookievalue"><a class="header" href="#prop-cookievalue">prop cookieValue</a></h3>
<pre><code class="language-cangjie">public prop cookieValue: String
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 cookie-value 值。</p>
<p>类型：String</p>
<h3 id="prop-domain"><a class="header" href="#prop-domain">prop domain</a></h3>
<pre><code class="language-cangjie">public prop domain: String
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 domain-av 值。</p>
<p>类型：String</p>
<h3 id="prop-expires"><a class="header" href="#prop-expires">prop expires</a></h3>
<pre><code class="language-cangjie">public prop expires: ?DateTime
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 expires-av 值。</p>
<p>类型：?DateTime</p>
<h3 id="prop-httponly"><a class="header" href="#prop-httponly">prop httpOnly</a></h3>
<pre><code class="language-cangjie">public prop httpOnly: Bool
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 httpOnly-av 值。</p>
<p>类型：Bool</p>
<h3 id="prop-maxage"><a class="header" href="#prop-maxage">prop maxAge</a></h3>
<pre><code class="language-cangjie">public prop maxAge: ?Int64
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 max-age-av 值。</p>
<p>类型：?Int64</p>
<h3 id="prop-others"><a class="header" href="#prop-others">prop others</a></h3>
<pre><code class="language-cangjie">public prop others: ArrayList&lt;String&gt;
</code></pre>
<p>功能：获取未被解析的属性。</p>
<p>类型：ArrayList&lt;String&gt;</p>
<h3 id="prop-path"><a class="header" href="#prop-path">prop path</a></h3>
<pre><code class="language-cangjie">public prop path: String
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 path-av 值。</p>
<p>类型：String</p>
<h3 id="prop-secure"><a class="header" href="#prop-secure">prop secure</a></h3>
<pre><code class="language-cangjie">public prop secure: Bool
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的 secure-av 值。</p>
<p>类型：Bool</p>
<h3 id="initstring-string-datetime-int64-string-string-bool-bool"><a class="header" href="#initstring-string-datetime-int64-string-string-bool-bool">init(String, String, ?DateTime, ?Int64, String, String, Bool, Bool)</a></h3>
<pre><code class="language-cangjie">public init(name: String, value: String, expires!: ?DateTime = None, maxAge!: ?Int64 = None,
    domain!: String = &quot;&quot;, path!: String = &quot;&quot;, secure!: Bool = false, httpOnly!: Bool = false)
</code></pre>
<p>功能：提供 <a href="http_package_classes.html#class-cookie">Cookie</a> 对象的公开构造器说明：该构造器会检查传入的各项属性是否满足协议要求，如果不满足则会产生 IllegalArgumentException。具体要求见 <a href="https://httpwg.org/specs/rfc6265.html#sane-set-cookie-syntax">RFC 6265 4.1.1.</a>。</p>
<blockquote>
<p><strong>注意：</strong></p>
<p><a href="http_package_classes.html#class-cookie">Cookie</a> 各属性中只有 cookie-name，cookie-value 是必需的，必须传入 name，value 参数，但 value 参数可以传入空字符串。</p>
</blockquote>
<p>参数：</p>
<ul>
<li>
<p>name: String - cookie-name 属性。</p>
<pre><code class="language-cangjie">name         = token 
token        = 1*tchar
tchar        = &quot;!&quot; / &quot;#&quot; / &quot;$&quot; / &quot;%&quot; / &quot;&amp;&quot; / &quot;'&quot; / &quot;*&quot;
               / &quot;+&quot; / &quot;-&quot; / &quot;.&quot; / &quot;^&quot; / &quot;_&quot; / &quot;`&quot; / &quot;|&quot; / &quot;~&quot;
               / DIGIT / ALPHA
</code></pre>
</li>
<li>
<p>value: String - cookie-value 属性。</p>
<pre><code class="language-cangjie">value        = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
            ; US-ASCII characters excluding CTLs,
            ; whitespace DQUOTE, comma, semicolon,
            ; and backslash
</code></pre>
</li>
<li>
<p>expires!: ?DateTime - 设置 <a href="http_package_classes.html#class-cookie">Cookie</a> 的过期时间，默认为 None，时间必须在 1601 年之后。</p>
</li>
<li>
<p>maxAge!: ?Int64 - <a href="http_package_classes.html#class-cookie">Cookie</a> 的最大生命周期，默认为 None，如果 <a href="http_package_classes.html#class-cookie">Cookie</a> 既有 expires 属性，也有 maxAge，则表示该 <a href="http_package_classes.html#class-cookie">Cookie</a> 只维护到会话结束（维护到 <a href="http_package_classes.html#class-client">Client</a> 关闭之前，<a href="http_package_classes.html#class-client">Client</a> 关闭之后设置了过期的 <a href="http_package_classes.html#class-cookie">Cookie</a> 也不再维护）。</p>
<pre><code class="language-cangjie">max-age-av     = &quot;Max-Age=&quot; non-zero-digit *DIGIT
non-zero-digit = %x31-39
                ; digits 1 through 9
DIGIT          = %x30-39
                ; digits 0 through 9
</code></pre>
</li>
<li>
<p>domain!: String - 默认为空字符串，表示该收到该 <a href="http_package_classes.html#class-cookie">Cookie</a> 的客户端只会发送该 <a href="http_package_classes.html#class-cookie">Cookie</a> 给原始服务器。如果设置了合法的 domain，则收到该 <a href="http_package_classes.html#class-cookie">Cookie</a> 的客户端只会发送该 <a href="http_package_classes.html#class-cookie">Cookie</a> 给所有该 domain 的子域（且满足其他属性条件要求才会发）。</p>
<pre><code class="language-cangjie">domain          = &lt;subdomain&gt; | &quot; &quot;
&lt;subdomain&gt;   ::= &lt;label&gt; | &lt;subdomain&gt; &quot;.&quot; &lt;label&gt;
&lt;label&gt;       ::= &lt;letter&gt; [ [ &lt;ldh-str&gt; ] &lt;let-dig&gt; ]
&lt;ldh-str&gt;     ::= &lt;let-dig-hyp&gt; | &lt;let-dig-hyp&gt; &lt;ldh-str&gt;
&lt;let-dig-hyp&gt; ::= &lt;let-dig&gt; | &quot;-&quot;
&lt;let-dig&gt;     ::= &lt;letter&gt; | &lt;digit&gt;
&lt;letter&gt;      ::= any one of the 52 alphabetic characters A through Z in upper case and a through z in lower case
&lt;digit&gt;       ::= any one of the ten digits 0 through 9
RFC 1035 2.3.1.
而 RFC 1123 2.1. 放松了对 label 首字符必须是 letter 的限制
因此，对 domain 的要求为：
1、总长度小于等于 255，由若干个 label 组成
2、label 与 label 之间通过 &quot;.&quot; 分隔，每个 label 长度小于等于 63
3、label 的开头和结尾必须是数字或者字母，label 的中间字符必须是数字、字母或者 &quot;-&quot;
</code></pre>
</li>
<li>
<p>path!: String - 默认为空字符串，客户端会根据 url 计算出默认的 path 属性，见 RFC 6265 5.1.4.。 收到该 <a href="http_package_classes.html#class-cookie">Cookie</a> 的客户端只会发送该 <a href="http_package_classes.html#class-cookie">Cookie</a> 给所有该 path 的子目录（且满足其他属性条件要求才会发）。</p>
<pre><code class="language-cangjie">path            = &lt;any RUNE except CTLs or &quot;;&quot;&gt;
RUNE            = &lt;any [USASCII] character&gt;
CTLs            = &lt;controls&gt;
</code></pre>
</li>
<li>
<p>secure!: Bool - 默认为 false，如果设置为 true，该 <a href="http_package_classes.html#class-cookie">Cookie</a> 只会在安全协议请求中发送。</p>
</li>
<li>
<p>httpOnly!: Bool - 默认为 false，如果设置为 true，该 <a href="http_package_classes.html#class-cookie">Cookie</a> 只会在 HTTP 协议请求中发送。</p>
</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 传入的参数不符合协议要求时抛出异常。</li>
</ul>
<h3 id="func-tosetcookiestring"><a class="header" href="#func-tosetcookiestring">func toSetCookieString()</a></h3>
<pre><code class="language-cangjie">public func toSetCookieString(): String
</code></pre>
<p>功能：提供将 <a href="http_package_classes.html#class-cookie">Cookie</a> 转成字符串形式的函数，方便 server 设置 <code>Set-Cookie</code> header。</p>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li><a href="http_package_classes.html#class-cookie">Cookie</a> 各属性（包含 name，value）在对象创建时就被检查了，因此 toSetCookieString() 函数不会产生异常；</li>
<li><a href="http_package_classes.html#class-cookie">Cookie</a> 必需的属性是 cookie-pair 即 cookie-name &quot;=&quot; cookie-value，cookie-value 可以为空字符串，toSetCookieString() 函数只会将设置过的属性写入字符串，即只有 &quot;cookie-name=&quot; 是必有的，其余部分是否存在取决于是否设置。</li>
</ul>
</blockquote>
<p>返回值：</p>
<ul>
<li>String - 字符串对象，用于设置 <code>Set-Cookie</code> header。</li>
</ul>
<h2 id="class-filehandler"><a class="header" href="#class-filehandler">class FileHandler</a></h2>
<pre><code class="language-cangjie">public class FileHandler &lt;: HttpRequestHandler {
    public init(path: String, handlerType!: FileHandlerType = DownLoad, bufferSize!: Int64 = 64 * 1024)
}
</code></pre>
<p>功能：用于处理文件下载或者文件上传。</p>
<p>文件下载：</p>
<ul>
<li>构造 <a href="http_package_classes.html#class-filehandler">FileHandler</a> 时需要传入待下载文件的路径，目前一个 <a href="http_package_classes.html#class-filehandler">FileHandler</a> 只能处理一个文件的下载；</li>
<li>下载文件只能使用 GET 请求，其他请求返回 400 状态码；</li>
<li>文件如果不存在，将返回 404 状态码。</li>
</ul>
<p>文件上传：</p>
<ul>
<li>构造 <a href="http_package_classes.html#class-filehandler">FileHandler</a> 时需要传入一个存在的目录路径，上传到服务端的文件将保存在这个目录中；</li>
<li>上传文件时只能使用 POST 请求，其他请求返回 400 状态码；</li>
<li>上传数据的 http 报文必须是 <code>multipart/form-data</code> 格式的，<code>Content-Type</code> 头字段的值为 <code>multipart/form-data; boundary=----XXXXX</code>；</li>
<li>上传文件的文件名存放在 <code>form-data</code> 数据报文中，报文数据格式为 <code>Content-Disposition: form-data; name=&quot;xxx&quot;; filename=&quot;xxxx&quot;</code>，文件名是 <code>filename</code> 字段的值；</li>
<li>目前 form-data 中必须包含 filename 字段；</li>
<li>如果请求报文不正确，将返回 400 状态码；</li>
<li>如果出现其他异常，例如文件处理异常，将返回 500 状态码。</li>
</ul>
<p>父类型：</p>
<ul>
<li><a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a></li>
</ul>
<h3 id="initstring-filehandlertype-int64"><a class="header" href="#initstring-filehandlertype-int64">init(String, FileHandlerType, Int64)</a></h3>
<pre><code class="language-cangjie">public init(path: String, handlerType!: FileHandlerType = DownLoad, bufferSize!: Int64 = 64 * 1024)
</code></pre>
<p>功能：<a href="http_package_classes.html#class-filehandler">FileHandler</a> 的构造函数。</p>
<p>参数：</p>
<ul>
<li>path: String - <a href="http_package_classes.html#class-filehandler">FileHandler</a> 构造时需要传入的文件或者目录路径字符串，上传模式中只能传入存在的目录路径；路径中存在../时，用户需要确认标准化后的绝对路径是期望传入的路径。</li>
<li>handlerType!: <a href="http_package_enums.html#enum-filehandlertype">FileHandlerType</a> - 构造 <a href="http_package_classes.html#class-filehandler">FileHandler</a> 时指定当前 <a href="http_package_classes.html#class-filehandler">FileHandler</a> 的工作模式，默认为 DownLoad 下载模式。</li>
<li>bufferSize!: Int64 - 内部从网络读取或者写入的缓冲区大小，默认值为 64*1024（64k），若小于 4096，则使用 4096 作为缓冲区大小。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 当 path 不存在时，抛出异常。</li>
<li>IllegalArgumentException - 参数错误时抛出异常，如 path 为空或者包含空字符串等。</li>
</ul>
<h3 id="func-handlehttpcontext"><a class="header" href="#func-handlehttpcontext">func handle(HttpContext)</a></h3>
<pre><code class="language-cangjie">public func handle(ctx: HttpContext): Unit
</code></pre>
<p>功能：根据请求对响应数据进行处理。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h2 id="class-funchandler"><a class="header" href="#class-funchandler">class FuncHandler</a></h2>
<pre><code class="language-cangjie">public class FuncHandler &lt;: HttpRequestHandler {
    public FuncHandler(let handler: (HttpContext) -&gt; Unit)
}
</code></pre>
<p>功能：<a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a> 接口包装类，把单个函数包装成 <a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a>。</p>
<p>父类型：</p>
<ul>
<li><a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a></li>
</ul>
<h3 id="funchandlerhttpcontext---unit"><a class="header" href="#funchandlerhttpcontext---unit">FuncHandler((HttpContext) -&gt; Unit)</a></h3>
<pre><code class="language-cangjie">public FuncHandler(let handler: (HttpContext) -&gt; Unit)
</code></pre>
<p>功能：<a href="http_package_classes.html#class-funchandler">FuncHandler</a> 的构造函数。</p>
<p>参数：</p>
<ul>
<li>handler: (<a href="http_package_classes.html#class-httpcontext">HttpContext</a>) -&gt; Unit - 是调用 handle 的处理函数。</li>
</ul>
<h3 id="func-handlehttpcontext-1"><a class="header" href="#func-handlehttpcontext-1">func handle(HttpContext)</a></h3>
<pre><code class="language-cangjie">public func handle(ctx: HttpContext): Unit
</code></pre>
<p>功能：处理 Http 请求。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h2 id="class-httpcontext"><a class="header" href="#class-httpcontext">class HttpContext</a></h2>
<pre><code class="language-cangjie">public class HttpContext
</code></pre>
<p>功能：Http 请求上下文，作为 <a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a>.handle 函数的参数在服务端使用。</p>
<h3 id="prop-clientcertificate"><a class="header" href="#prop-clientcertificate">prop clientCertificate</a></h3>
<pre><code class="language-cangjie">public prop clientCertificate: ?Array&lt;X509Certificate&gt;
</code></pre>
<p>功能：获取 Http 客户端证书。</p>
<p>类型：?Array&lt;<a href="../../../crypto/x509/x509_package_api/x509_package_classes.html#class-x509certificate">X509Certificate</a>&gt;</p>
<h3 id="prop-request"><a class="header" href="#prop-request">prop request</a></h3>
<pre><code class="language-cangjie">public prop request: HttpRequest
</code></pre>
<p>功能：获取 Http 请求。</p>
<p>类型：<a href="http_package_classes.html#class-httprequest">HttpRequest</a></p>
<h3 id="prop-responsebuilder"><a class="header" href="#prop-responsebuilder">prop responseBuilder</a></h3>
<pre><code class="language-cangjie">public prop responseBuilder: HttpResponseBuilder
</code></pre>
<p>功能：获取 Http 响应构建器。</p>
<p>类型：<a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a></p>
<h2 id="class-httpheaders"><a class="header" href="#class-httpheaders">class HttpHeaders</a></h2>
<pre><code class="language-cangjie">public class HttpHeaders &lt;: Iterable&lt;(String, Collection&lt;String&gt;)&gt;
</code></pre>
<p>功能：此类用于表示 Http 报文中的 header 和 trailer，定义了相关增、删、改、查操作。</p>
<blockquote>
<p><strong>说明：</strong></p>
<ul>
<li>header 和 trailer 为键值映射集，由若干 field-line 组成，每一个 field-line 包含一个键 (field -name) 和若干值 (field-value)。</li>
<li>field-name 由 token 字符组成，不区分大小写，在该类中将转为小写保存。</li>
<li>field-value 由 vchar，SP 和 HTAB 组成，vchar 表示可见的 US-ASCII 字符，不得包含前后空格，不得为空值。</li>
<li>详见 <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-fields">rfc 9110</a>。</li>
</ul>
</blockquote>
<p>示例:</p>
<pre><code class="language-text">Example-Field: Foo, Bar
key: Example-Field, value: Foo, Bar
field-name = token
token = 1*tchar
tchar = &quot;!&quot; / &quot;#&quot; / &quot;$&quot; / &quot;%&quot; / &quot;&amp;&quot; / &quot;'&quot; / &quot;*&quot;
/ &quot;+&quot; / &quot;-&quot; / &quot;.&quot; / &quot;^&quot; / &quot;_&quot; / &quot;`&quot; / &quot;|&quot; / &quot;~&quot;
/ DIGIT / ALPHA
; any VCHAR, except delimiters
</code></pre>
<p>父类型：</p>
<ul>
<li>Iterable&lt;(String, Collection&lt;String&gt;)&gt;</li>
</ul>
<h3 id="func-addstring-string"><a class="header" href="#func-addstring-string">func add(String, String)</a></h3>
<pre><code class="language-cangjie">public func add(name: String, value: String): Unit
</code></pre>
<p>功能：添加指定键值对。如果 name 已经存在，将在其对应的值列表中添加 value；如果 name 不存在，则添加 name 字段及其值 value。</p>
<p>参数：</p>
<ul>
<li>name: String - <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 的字段名称。</li>
<li>value: String - <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 的字段值。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name/value 包含不合法元素，将抛出此异常。</li>
</ul>
<h3 id="func-delstring"><a class="header" href="#func-delstring">func del(String)</a></h3>
<pre><code class="language-cangjie">public func del(name: String): Unit
</code></pre>
<p>功能：删除指定 name 对应的键值对。</p>
<p>参数：</p>
<ul>
<li>name: String - 删除的字段名称。</li>
</ul>
<h3 id="func-getstring-1"><a class="header" href="#func-getstring-1">func get(String)</a></h3>
<pre><code class="language-cangjie">public func get(name: String): Collection&lt;String&gt;
</code></pre>
<p>功能：获取指定 name 对应的 value 值。</p>
<p>参数：</p>
<ul>
<li>name: String - 字段名称，不区分大小写。</li>
</ul>
<p>返回值：</p>
<ul>
<li>Collection&lt;String&gt; - name 对应的 value 集合，如果指定 name 不存在，返回空集合。</li>
</ul>
<h3 id="func-getfirststring"><a class="header" href="#func-getfirststring">func getFirst(String)</a></h3>
<pre><code class="language-cangjie">public func getFirst(name: String): ?String
</code></pre>
<p>功能：获取指定 name 对应的第一个 value 值。</p>
<p>参数：</p>
<ul>
<li>name: String - 字段名称，不区分大小写。</li>
</ul>
<p>返回值：</p>
<ul>
<li>?String - name 对应的第一个 value 值，如果指定 name 不存在，返回 None。</li>
</ul>
<h3 id="func-isempty"><a class="header" href="#func-isempty">func isEmpty()</a></h3>
<pre><code class="language-cangjie">public func isEmpty(): Bool
</code></pre>
<p>功能：判断当前实例是否为空，即没有任何键值对。</p>
<p>返回值：</p>
<ul>
<li>Bool - 如果当前实例为空，返回 true，否则返回 false。</li>
</ul>
<h3 id="func-iterator"><a class="header" href="#func-iterator">func iterator()</a></h3>
<pre><code class="language-cangjie">public func iterator(): Iterator&lt;(String, Collection&lt;String&gt;)&gt;
</code></pre>
<p>功能：获取迭代器，可用于遍历所有键值对。</p>
<p>返回值：</p>
<ul>
<li>Iterator&lt;(String, Collection&lt;String&gt;)&gt; - 该键值集的迭代器。</li>
</ul>
<h3 id="func-setstring-string"><a class="header" href="#func-setstring-string">func set(String, String)</a></h3>
<pre><code class="language-cangjie">public func set(name: String, value: String): Unit
</code></pre>
<p>功能：设置指定键值对。如果 name 已经存在，传入的 value 将会覆盖之前的值。</p>
<p>参数：</p>
<ul>
<li>name: String - <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 的字段名称。</li>
<li>value: String - <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 的字段值。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name/values 包含不合法元素，将抛出此异常。</li>
</ul>
<h2 id="class-httprequest"><a class="header" href="#class-httprequest">class HttpRequest</a></h2>
<pre><code class="language-cangjie">public class HttpRequest &lt;: ToString
</code></pre>
<p>功能：此类为 Http 请求类。</p>
<p>客户端发送请求时，需要构造一个 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 实例，再编码成字节报文发出。</p>
<p>服务端处理请求时，需要把收到的请求解析成 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 实例，并传给 handler 处理函数。</p>
<p>父类型：</p>
<ul>
<li>ToString</li>
</ul>
<h3 id="prop-body"><a class="header" href="#prop-body">prop body</a></h3>
<pre><code class="language-cangjie">public prop body: InputStream
</code></pre>
<p>功能：获取 body。</p>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li>body 不支持并发读取；</li>
<li>默认 InputStream 实现类的 read 函数不支持多次读取。</li>
</ul>
</blockquote>
<p>类型：InputStream</p>
<h3 id="prop-bodysize"><a class="header" href="#prop-bodysize">prop bodySize</a></h3>
<pre><code class="language-cangjie">public prop bodySize: Option&lt;Int64&gt;
</code></pre>
<p>功能：获取请求 body 长度。</p>
<ul>
<li>如果未设置 body，则 bodySize 为 Some(0)；</li>
<li>如果 body 长度已知，即通过 Array&lt;UInt8&gt; 或 String 传入 body，或传入的 InputStream 有确定的 length (length &gt;= 0)，则 bodySize 为 Some(Int64)；</li>
<li>如果 body 长度未知，即通过用户自定义的 InputStream 实例传入 body 且 InputStream 实例没有确定的 length (length &lt; 0)，则 bodySize 为 None。</li>
</ul>
<p>类型：Option&lt;Int64&gt;</p>
<h3 id="prop-close"><a class="header" href="#prop-close">prop close</a></h3>
<pre><code class="language-cangjie">public prop close: Bool
</code></pre>
<p>功能：表示该请求 header 是否包含 <code>Connection: close</code>。</p>
<ul>
<li>对于服务端，close 为 true 表示处理完该请求应该关闭连接。</li>
<li>对于客户端，close 为 true 表示如果收到响应后服务端未关闭连接，客户端应主动关闭连接。</li>
</ul>
<p>类型：Bool</p>
<h3 id="prop-form"><a class="header" href="#prop-form">prop form</a></h3>
<pre><code class="language-cangjie">public prop form: Form
</code></pre>
<p>功能：获取请求中的表单信息。</p>
<ul>
<li>如果请求方法为 POST，PUT，PATCH，且 content-type 包含 application/x-www-form-urlencoded，获取请求 body 部分，用 form 格式解析；</li>
<li>如果请求方法不为 POST，PUT，PATCH，获取请求 url 中 query 部分。</li>
</ul>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li>如果用该接口读取了 body，body 已被消费完，后续将无法通过 body.read 读取 body；</li>
<li>如果 form 不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-form">Form</a> 格式，抛 <a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> 异常。</li>
</ul>
</blockquote>
<p>类型：<a href="../../../encoding/url/url_package_api/url_package_classes.html#class-form">Form</a></p>
<h3 id="prop-headers"><a class="header" href="#prop-headers">prop headers</a></h3>
<pre><code class="language-cangjie">public prop headers: HttpHeaders
</code></pre>
<p>功能：获取 headers，headers 详述见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类，获取后，可通过调用 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 实例成员函数，修改该请求的 headers。</p>
<p>类型：<a href="http_package_classes.html#class-httpheaders">HttpHeaders</a></p>
<h3 id="prop-method"><a class="header" href="#prop-method">prop method</a></h3>
<pre><code class="language-cangjie">public prop method: String
</code></pre>
<p>功能：获取 method，如 &quot;GET&quot;, &quot;POST&quot;，request 实例的 method 无法修改。</p>
<p>类型：String</p>
<h3 id="prop-readtimeout-1"><a class="header" href="#prop-readtimeout-1">prop readTimeout</a></h3>
<pre><code class="language-cangjie">public prop readTimeout: ?Duration
</code></pre>
<p>功能：表示该请求的请求级读超时时间。None 表示没有设置；Some(Duration) 表示设置了读超时时间。</p>
<p>类型：?Duration</p>
<h3 id="prop-remoteaddr"><a class="header" href="#prop-remoteaddr">prop remoteAddr</a></h3>
<pre><code class="language-cangjie">public prop remoteAddr: String
</code></pre>
<p>功能：用于服务端，获取对端地址，即客户端地址，格式为 ip: port，用户无法设置，自定义的 request 对象调用该属性返回 &quot;&quot;，服务端 handler 中调用该属性返回客户端地址。</p>
<p>类型：String</p>
<h3 id="prop-trailers"><a class="header" href="#prop-trailers">prop trailers</a></h3>
<pre><code class="language-cangjie">public prop trailers: HttpHeaders
</code></pre>
<p>功能：获取 trailers，trailers 详述见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类，获取后，可通过调用 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 实例成员函数，修改该请求的 trailers。</p>
<p>类型：<a href="http_package_classes.html#class-httpheaders">HttpHeaders</a></p>
<h3 id="prop-url"><a class="header" href="#prop-url">prop url</a></h3>
<pre><code class="language-cangjie">public prop url: URL
</code></pre>
<p>功能：获取 url，表示客户端访问的 url。</p>
<p>类型：<a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a></p>
<h3 id="prop-version"><a class="header" href="#prop-version">prop version</a></h3>
<pre><code class="language-cangjie">public prop version: Protocol
</code></pre>
<p>功能：获取 http 版本，如 HTTP1_1 和 HTTP2_0，request 实例的 version 无法修改。</p>
<p>类型：<a href="http_package_enums.html#enum-protocol">Protocol</a></p>
<h3 id="prop-writetimeout-1"><a class="header" href="#prop-writetimeout-1">prop writeTimeout</a></h3>
<pre><code class="language-cangjie">public prop writeTimeout: ?Duration
</code></pre>
<p>功能：表示该请求的请求级写超时时间，None 表示没有设置；Some(Duration) 表示设置了写超时时间。</p>
<p>类型：?Duration</p>
<h3 id="func-tostring"><a class="header" href="#func-tostring">func toString()</a></h3>
<pre><code class="language-cangjie">public override func toString(): String
</code></pre>
<p>功能：把请求转换为字符串，包括 start line，headers，body size，trailers。
例如：<code>&quot;GET /path HTTP/1.1\r\nhost: www.example.com\r\n\r\nbody size: 5\r\nbar: foo\r\n&quot;</code>。</p>
<p>返回值：</p>
<ul>
<li>String - 请求的字符串表示。</li>
</ul>
<h2 id="class-httprequestbuilder"><a class="header" href="#class-httprequestbuilder">class HttpRequestBuilder</a></h2>
<pre><code class="language-cangjie">public class HttpRequestBuilder {
    public init()
    public init(request: HttpRequest)
}
</code></pre>
<p>功能：<a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 类用于构造 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 实例。</p>
<h3 id="init-1"><a class="header" href="#init-1">init()</a></h3>
<pre><code class="language-cangjie">public init()
</code></pre>
<p>功能：构造一个新 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a>。</p>
<h3 id="inithttprequest"><a class="header" href="#inithttprequest">init(HttpRequest)</a></h3>
<pre><code class="language-cangjie">public init(request: HttpRequest)
</code></pre>
<p>功能： 通过 request 构造一个具有 request 属性的 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a>。由于 body 成员是一个 InputStream，对原始的 request 的 body 的操作会影响到复制得到的 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 的 body。<a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 的 headers 和 trailers 是入参 request 的深拷贝。其余元素都是入参 request 的浅拷贝（因为是不可变对象，无需深拷贝）。</p>
<p>参数：</p>
<ul>
<li>request: <a href="http_package_classes.html#class-httprequest">HttpRequest</a> - 传入的 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 对象。</li>
</ul>
<h3 id="func-addheadershttpheaders"><a class="header" href="#func-addheadershttpheaders">func addHeaders(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func addHeaders(headers: HttpHeaders): HttpRequestBuilder
</code></pre>
<p>功能：向请求 header 添加参数 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 中的键值对。</p>
<p>参数：</p>
<ul>
<li>headers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 header 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-addtrailershttpheaders"><a class="header" href="#func-addtrailershttpheaders">func addTrailers(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func addTrailers(trailers: HttpHeaders): HttpRequestBuilder
</code></pre>
<p>功能：向请求 trailer 添加参数 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 中的键值对。</p>
<p>参数：</p>
<ul>
<li>trailers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 trailer 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodyarrayuint8"><a class="header" href="#func-bodyarrayuint8">func body(Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func body(body: Array&lt;UInt8&gt;): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 body。如果已经设置过，调用该函数将替换原 body。</p>
<p>参数：</p>
<ul>
<li>body: Array&lt;UInt8&gt; - 字节数组形式的请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodyinputstream"><a class="header" href="#func-bodyinputstream">func body(InputStream)</a></h3>
<pre><code class="language-cangjie">public func body(body: InputStream): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 body。如果已经设置过，调用该函数将替换原 body。</p>
<p>参数：</p>
<ul>
<li>body: InputStream - 流形式的请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodystring"><a class="header" href="#func-bodystring">func body(String)</a></h3>
<pre><code class="language-cangjie">public func body(body: String): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 body，如果已经设置过，调用该函数将替换原 body调用该函数设置请求 body，则 body 将以内置的 InputStream 实现类表示，其大小已知。</p>
<p>参数：</p>
<ul>
<li>body: String - 字符串形式的请求体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-build-1"><a class="header" href="#func-build-1">func build()</a></h3>
<pre><code class="language-cangjie">public func build(): HttpRequest
</code></pre>
<p>功能：根据 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例生成一个 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 实例。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequest">HttpRequest</a> - 根据当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例构造出来的 <a href="http_package_classes.html#class-httprequest">HttpRequest</a> 实例。</li>
</ul>
<h3 id="func-connect"><a class="header" href="#func-connect">func connect()</a></h3>
<pre><code class="language-cangjie">public func connect(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;CONNECT&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-delete"><a class="header" href="#func-delete">func delete()</a></h3>
<pre><code class="language-cangjie">public func delete(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;DELETE&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-get"><a class="header" href="#func-get">func get()</a></h3>
<pre><code class="language-cangjie">public func get(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;GET&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-head"><a class="header" href="#func-head">func head()</a></h3>
<pre><code class="language-cangjie">public func head(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;HEAD&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-headerstring-string"><a class="header" href="#func-headerstring-string">func header(String, String)</a></h3>
<pre><code class="language-cangjie">public func header(name: String, value: String): HttpRequestBuilder
</code></pre>
<p>功能：向请求 header 添加指定键值对，规则同 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类的 add 函数。</p>
<p>参数：</p>
<ul>
<li>name: String - 请求头的 key。</li>
<li>value: String - 请求头的 value。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name 或 value 包含不合法元素，将抛出此异常。</li>
</ul>
<h3 id="func-methodstring"><a class="header" href="#func-methodstring">func method(String)</a></h3>
<pre><code class="language-cangjie">public func method(method: String): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 method，默认请求 method 为 &quot;GET&quot;。</p>
<p>参数：</p>
<ul>
<li>method: String - 请求方法，必须由 token 字符组成，如果传入空字符串，method 值将自动设置为 &quot;GET&quot;。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 参数 method 非法时抛出此异常。</li>
</ul>
<h3 id="func-options"><a class="header" href="#func-options">func options()</a></h3>
<pre><code class="language-cangjie">public func options(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;OPTIONS&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-post"><a class="header" href="#func-post">func post()</a></h3>
<pre><code class="language-cangjie">public func post(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;POST&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-priorityint64-bool"><a class="header" href="#func-priorityint64-bool">func priority(Int64, Bool)</a></h3>
<pre><code class="language-cangjie">public func priority(urg: Int64, inc: Bool): HttpRequestBuilder
</code></pre>
<p>功能：设置 priority 头的便捷函数，调用此函数后，将生成 priority 头，形如：&quot;priority: urgency=x, i&quot;。如果通过设置请求头的函数设置了 priority 字段，调用此函数无效。如果多次调用此函数，以最后一次为准。</p>
<p>参数：</p>
<ul>
<li>urg: Int64 - 表示请求优先级，取值范围为 [0, 7]，0 表示最高优先级。</li>
<li>inc: Bool - 表示请求是否需要增量处理，为 true 表示希望服务器并发处理与之同 urg 同 inc 的请求，为 false 表示不希望服务器并发处理。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="./http_package_exceptions.html#class-httpexception">HttpException</a> - 当参数 urg 取值非法，即不在 [0, 7] 范围内时，抛出异常。</li>
</ul>
<h3 id="func-put"><a class="header" href="#func-put">func put()</a></h3>
<pre><code class="language-cangjie">public func put(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;PUT&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-readtimeoutduration-1"><a class="header" href="#func-readtimeoutduration-1">func readTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func readTimeout(timeout: Duration): HttpRequestBuilder
</code></pre>
<p>功能：设置此请求的读超时时间。如果传入的 Duration 为负，则会自动转为 0。如果用户设置了此读超时时间，那么该请求的读超时以此为准；如果用户没有设置，那么该请求的读超时以 <a href="http_package_classes.html#class-client">Client</a> 为准。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 用户设置的此请求的读超时时间。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-setheadershttpheaders"><a class="header" href="#func-setheadershttpheaders">func setHeaders(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func setHeaders(headers: HttpHeaders): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 header，如果已经设置过，调用该函数将替换原 header。</p>
<p>参数：</p>
<ul>
<li>headers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 header 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-settrailershttpheaders"><a class="header" href="#func-settrailershttpheaders">func setTrailers(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func setTrailers(trailers: HttpHeaders): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 trailer，如果已经设置过，调用该函数将替换原 trailer。</p>
<p>参数：</p>
<ul>
<li>trailers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 trailer 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-trace"><a class="header" href="#func-trace">func trace()</a></h3>
<pre><code class="language-cangjie">public func trace(): HttpRequestBuilder
</code></pre>
<p>功能：构造 method 为 &quot;TRACE&quot; 的请求的便捷函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-trailerstring-string"><a class="header" href="#func-trailerstring-string">func trailer(String, String)</a></h3>
<pre><code class="language-cangjie">public func trailer(name: String, value: String): HttpRequestBuilder
</code></pre>
<p>功能：向请求 trailer 添加指定键值对，规则同 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类的 add 函数。</p>
<p>参数：</p>
<ul>
<li>name: String - 请求头的 key。</li>
<li>value: String - 请求头的 value。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name 或 value 包含不合法元素，将抛出此异常。</li>
</ul>
<h3 id="func-urlstring"><a class="header" href="#func-urlstring">func url(String)</a></h3>
<pre><code class="language-cangjie">public func url(rawUrl: String): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 url，默认 url 为空的 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 对象。</p>
<p>参数：</p>
<ul>
<li>rawUrl: String - 待解析成 url 对象的字符串，该字符串格式详见 <a href="../../../encoding/url/url_package_api/url_package_classes.html#static-func-parsestring">URL.parse</a> 函数。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 当被编码的字符不符合 UTF8 的字节序列规则时，抛出异常。</li>
<li><a href="../../../encoding/url/url_package_api/url_package_exceptions.html#class-urlsyntaxexception">UrlSyntaxException</a> - 当传入字符串不符合 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 格式时，抛出异常。</li>
</ul>
<h3 id="func-urlurl"><a class="header" href="#func-urlurl">func url(URL)</a></h3>
<pre><code class="language-cangjie">public func url(url: URL): HttpRequestBuilder
</code></pre>
<p>功能：设置请求 url，默认 url 为空的 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> 对象，即 <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a>.parse(&quot;&quot;)。</p>
<p>参数：</p>
<ul>
<li>url: <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> - URL 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-versionprotocol"><a class="header" href="#func-versionprotocol">func version(Protocol)</a></h3>
<pre><code class="language-cangjie">public func version(version: Protocol): HttpRequestBuilder
</code></pre>
<p>功能：设置请求的 http 协议版本，默认为 UnknownProtocol(&quot;&quot;)，客户端会根据 tls 配置自动选择协议。</p>
<p>参数：</p>
<ul>
<li>version: <a href="http_package_enums.html#enum-protocol">Protocol</a> - 协议版本。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-writetimeoutduration-1"><a class="header" href="#func-writetimeoutduration-1">func writeTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func writeTimeout(timeout: Duration): HttpRequestBuilder
</code></pre>
<p>功能：设置此请求的写超时时间。如果传入的 Duration 为负，则会自动转为 0。如果用户设置了此写超时时间，那么该请求的写超时以此为准；如果用户没有设置，那么该请求的写超时以 <a href="http_package_classes.html#class-client">Client</a> 为准。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 用户设置的此请求的写超时时间。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> - 当前 <a href="http_package_classes.html#class-httprequestbuilder">HttpRequestBuilder</a> 实例的引用。</li>
</ul>
<h2 id="class-httpresponse"><a class="header" href="#class-httpresponse">class HttpResponse</a></h2>
<pre><code class="language-cangjie">public class HttpResponse &lt;: ToString
</code></pre>
<p>功能：Http 响应类。</p>
<p>此类定义了 http 中响应 Response 的相关接口，客户端用该类读取服务端返回的响应。</p>
<p>父类型：</p>
<ul>
<li>ToString</li>
</ul>
<h3 id="prop-body-1"><a class="header" href="#prop-body-1">prop body</a></h3>
<pre><code class="language-cangjie">public prop body: InputStream
</code></pre>
<p>功能：获取 body。</p>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li>body 不支持并发读取；</li>
<li>默认 InputStream 实现类的 read 函数不支持多次读取。</li>
</ul>
</blockquote>
<p>类型：InputStream</p>
<h3 id="prop-bodysize-1"><a class="header" href="#prop-bodysize-1">prop bodySize</a></h3>
<pre><code class="language-cangjie">public prop bodySize: Option&lt;Int64&gt;
</code></pre>
<p>功能：获取响应 body 长度。</p>
<blockquote>
<ul>
<li>如果未设置 body，则 bodySize 为 Some(0)；</li>
<li>如果 body 长度已知，即通过 Array&lt;UInt8&gt; 或 String 传入 body，或传入的 InputStream 有确定的 length (length &gt;= 0)，则 bodySize 为 Some(Int64)；</li>
<li>如果 body 长度未知，即通过用户自定义的 InputStream 实例传入 body 且 InputStream 实例没有确定的 length (length &lt; 0)，则 bodySize 为 None。</li>
</ul>
</blockquote>
<p>类型：Option&lt;Int64&gt;</p>
<h3 id="prop-close-1"><a class="header" href="#prop-close-1">prop close</a></h3>
<pre><code class="language-cangjie">public prop close: Bool
</code></pre>
<p>功能：表示该响应 header 是否包含 Connection: close。</p>
<p>对于服务端，close 为 true 表示处理完该请求应该关闭连接；</p>
<p>对于客户端，close 为 true 表示如果收到响应后服务端未关闭连接，客户端应主动关闭连接。</p>
<p>类型：Bool</p>
<h3 id="prop-headers-1"><a class="header" href="#prop-headers-1">prop headers</a></h3>
<pre><code class="language-cangjie">public prop headers: HttpHeaders
</code></pre>
<p>功能：获取 headers，headers 详述见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类，获取后，可通过调用 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 实例成员函数，修改该请求的 headers。</p>
<p>类型：<a href="http_package_classes.html#class-httpheaders">HttpHeaders</a></p>
<h3 id="prop-request-1"><a class="header" href="#prop-request-1">prop request</a></h3>
<pre><code class="language-cangjie">public prop request: Option&lt;HttpRequest&gt;
</code></pre>
<p>功能：获取该响应对应的请求，默认为 None。</p>
<p>类型：Option&lt;<a href="http_package_classes.html#class-httprequest">HttpRequest</a>&gt;</p>
<h3 id="prop-status"><a class="header" href="#prop-status">prop status</a></h3>
<pre><code class="language-cangjie">public prop status: UInt16
</code></pre>
<p>功能：获取响应的状态码，默认值为 200。状态码由 100~599 的三位数字组成，状态码所反映的具体信息可参考 <a href="https://httpwg.org/specs/rfc9110.html#status.codes">RFC 9110</a>。</p>
<p>类型：UInt16</p>
<h3 id="prop-trailers-1"><a class="header" href="#prop-trailers-1">prop trailers</a></h3>
<pre><code class="language-cangjie">public prop trailers: HttpHeaders
</code></pre>
<p>功能：获取 trailers，trailers 详述见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类，获取后，可通过调用 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 实例成员函数，修改该请求的 trailers。</p>
<p>类型：<a href="http_package_classes.html#class-httpheaders">HttpHeaders</a></p>
<h3 id="prop-version-1"><a class="header" href="#prop-version-1">prop version</a></h3>
<pre><code class="language-cangjie">public prop version: Protocol
</code></pre>
<p>功能：获取响应的协议版本，默认值为 <a href="./http_package_enums.html#enum-Protocol">HTTP1_1</a>。</p>
<p>类型：<a href="http_package_enums.html#enum-protocol">Protocol</a></p>
<h3 id="func-tostring-1"><a class="header" href="#func-tostring-1">func toString()</a></h3>
<pre><code class="language-cangjie">public override func toString(): String
</code></pre>
<p>功能：把响应转换为字符串，包括 status-line，headers，body size， trailers。</p>
<p>例如：HTTP/1.1 200 OK\r\ncontent-length: 5\r\n\r\nbody size: 5\r\nbar: foo\r\n。</p>
<p>返回值：</p>
<ul>
<li>String - 响应的字符串表示。</li>
</ul>
<h3 id="extend-httpresponse"><a class="header" href="#extend-httpresponse">extend HttpResponse</a></h3>
<pre><code class="language-cangjie">extend HttpResponse
</code></pre>
<p>功能：为 HttpResonse 扩展 HTTP/2.0 特有的方法。</p>
<h4 id="func-getpush"><a class="header" href="#func-getpush">func getPush()</a></h4>
<pre><code class="language-cangjie">public func getPush(): Option&lt;ArrayList&lt;HttpResponse&gt;&gt;
</code></pre>
<p>功能：获取服务器推送的响应，返回 None 代表未开启服务器推送功能，返回空 ArrayList 代表无服务器推送的响应。</p>
<p>返回值：</p>
<ul>
<li>Option&lt;ArrayList&lt;<a href="http_package_classes.html#class-httpresponse">HttpResponse</a>&gt;&gt; - 服务器推送的响应列表。</li>
</ul>
<h2 id="class-httpresponsebuilder"><a class="header" href="#class-httpresponsebuilder">class HttpResponseBuilder</a></h2>
<pre><code class="language-cangjie">public class HttpResponseBuilder {
    public init()
}
</code></pre>
<p>功能：用于构造 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a> 实例。</p>
<h3 id="init-2"><a class="header" href="#init-2">init()</a></h3>
<pre><code class="language-cangjie">public init()
</code></pre>
<p>功能：构造一个新 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a>。</p>
<h3 id="func-addheadershttpheaders-1"><a class="header" href="#func-addheadershttpheaders-1">func addHeaders(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func addHeaders(headers: HttpHeaders): HttpResponseBuilder
</code></pre>
<p>功能：向响应 header 添加参数 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 中的键值对。</p>
<p>参数：</p>
<ul>
<li>headers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 header 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-addtrailershttpheaders-1"><a class="header" href="#func-addtrailershttpheaders-1">func addTrailers(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func addTrailers(trailers: HttpHeaders): HttpResponseBuilder
</code></pre>
<p>功能：向响应 trailer 添加参数 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 中的键值对。</p>
<p>参数：</p>
<ul>
<li>trailers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 trailer 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodyarrayuint8-1"><a class="header" href="#func-bodyarrayuint8-1">func body(Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func body(body: Array&lt;UInt8&gt;): HttpResponseBuilder
</code></pre>
<p>功能：设置响应 body，如果已经设置过，调用该函数将替换原 body。</p>
<p>参数：</p>
<ul>
<li>body: Array&lt;UInt8&gt; - 字节数组形式的响应体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodyinputstream-1"><a class="header" href="#func-bodyinputstream-1">func body(InputStream)</a></h3>
<pre><code class="language-cangjie">public func body(body: InputStream): HttpResponseBuilder
</code></pre>
<p>功能：设置响应 body，如果已经设置过，调用该函数将替换原 body调用该函数设置请求 body。</p>
<p>参数：</p>
<ul>
<li>body: InputStream - 流形式的响应体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-bodystring-1"><a class="header" href="#func-bodystring-1">func body(String)</a></h3>
<pre><code class="language-cangjie">public func body(body: String): HttpResponseBuilder
</code></pre>
<p>功能：设置响应 body，如果已经设置过，调用该函数将替换原 body调用该函数设置请求 body。</p>
<p>参数：</p>
<ul>
<li>body: String - 字符串形式的响应体。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-build-2"><a class="header" href="#func-build-2">func build()</a></h3>
<pre><code class="language-cangjie">public func build(): HttpResponse
</code></pre>
<p>功能：根据 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例生成一个 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a> 实例。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponse">HttpResponse</a> - 根据当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例构造出来的 <a href="http_package_classes.html#class-httpresponse">HttpResponse</a> 实例。</li>
</ul>
<h3 id="func-headerstring-string-1"><a class="header" href="#func-headerstring-string-1">func header(String, String)</a></h3>
<pre><code class="language-cangjie">public func header(name: String, value: String): HttpResponseBuilder
</code></pre>
<p>功能：向响应 header 添加指定键值对，规则同 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类的 add 函数。</p>
<p>参数：</p>
<ul>
<li>name: String - 响应头的 key。</li>
<li>value: String - 响应头的 value。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name 或 value 包含不合法元素，将抛出此异常。</li>
</ul>
<h3 id="func-requesthttprequest"><a class="header" href="#func-requesthttprequest">func request(HttpRequest)</a></h3>
<pre><code class="language-cangjie">public func request(request: HttpRequest): HttpResponseBuilder
</code></pre>
<p>功能：设置响应对应的请求。</p>
<p>参数：</p>
<ul>
<li>request: <a href="http_package_classes.html#class-httprequest">HttpRequest</a> - 响应对应的请求。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-setheadershttpheaders-1"><a class="header" href="#func-setheadershttpheaders-1">func setHeaders(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func setHeaders(headers: HttpHeaders): HttpResponseBuilder
</code></pre>
<p>功能：设置响应 header，如果已经设置过，调用该函数将替换原 header。</p>
<p>参数：</p>
<ul>
<li>headers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 header 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-settrailershttpheaders-1"><a class="header" href="#func-settrailershttpheaders-1">func setTrailers(HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func setTrailers(trailers: HttpHeaders): HttpResponseBuilder
</code></pre>
<p>功能：设置响应 trailer，如果已经设置过，调用该函数将替换原 trailer。</p>
<p>参数：</p>
<ul>
<li>trailers: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 传入的 trailer 对象。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h3 id="func-statusuint16"><a class="header" href="#func-statusuint16">func status(UInt16)</a></h3>
<pre><code class="language-cangjie">public func status(status: UInt16): HttpResponseBuilder
</code></pre>
<p>功能：设置 http 响应状态码。</p>
<p>参数：</p>
<ul>
<li>status: UInt16 - 传入的状态码的值。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果设置响应状态码不在 100~599 这个区间内，则抛出此异常。</li>
</ul>
<h3 id="func-trailerstring-string-1"><a class="header" href="#func-trailerstring-string-1">func trailer(String, String)</a></h3>
<pre><code class="language-cangjie">public func trailer(name: String, value: String): HttpResponseBuilder
</code></pre>
<p>功能：向响应 trailer 添加指定键值对，规则同 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类的 add 函数。</p>
<p>参数：</p>
<ul>
<li>name: String - 响应头的 key。</li>
<li>value: String - 响应头的 value。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 如果传入的 name 或 value 包含不合法元素，将抛出此异常。</li>
</ul>
<h3 id="func-versionprotocol-1"><a class="header" href="#func-versionprotocol-1">func version(Protocol)</a></h3>
<pre><code class="language-cangjie">public func version(version: Protocol): HttpResponseBuilder
</code></pre>
<p>功能：设置 http 响应协议版本。</p>
<p>参数：</p>
<ul>
<li>version: <a href="http_package_enums.html#enum-protocol">Protocol</a> - 协议版本。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> - 当前 <a href="http_package_classes.html#class-httpresponsebuilder">HttpResponseBuilder</a> 实例的引用。</li>
</ul>
<h2 id="class-httpresponsepusher"><a class="header" href="#class-httpresponsepusher">class HttpResponsePusher</a></h2>
<pre><code class="language-cangjie">public class HttpResponsePusher
</code></pre>
<p>功能：HTTP/2 服务器推送。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>如果服务器收到请求后，认为客户端后续还需要某些关联资源，可以将其提前推送到客户端；
服务端推送包括推送请求和推送响应；
启用服务端推送需要先调用 push 函数发送推送请求，并向服务器注册该请求对应的 handler，用以生成推送响应；
客户端可设置拒绝服务端推送；
不允许嵌套推送，即不允许在推送请求对应的 handler 中再次推送。嵌套推送情况下，服务端将不执行推送，并打印日志进行提示。</p>
</blockquote>
<h3 id="static-func-getpusherhttpcontext"><a class="header" href="#static-func-getpusherhttpcontext">static func getPusher(HttpContext)</a></h3>
<pre><code class="language-cangjie">public static func getPusher(ctx: HttpContext): ?HttpResponsePusher
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-httpresponsepusher">HttpResponsePusher</a> 实例，如果客户端拒绝推送，将返回 None。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<p>返回值：</p>
<ul>
<li>?<a href="http_package_classes.html#class-httpresponsepusher">HttpResponsePusher</a> - 获得的 <a href="http_package_classes.html#class-httpresponsepusher">HttpResponsePusher</a>。</li>
</ul>
<h3 id="func-pushstring-string-httpheaders"><a class="header" href="#func-pushstring-string-httpheaders">func push(String, String, HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public func push(path: String, method: String, header: HttpHeaders): Unit
</code></pre>
<p>功能：向客户端发送推送请求，path 为请求地址，method 为请求方法，header 为请求头。</p>
<p>参数：</p>
<ul>
<li>path: String - 推送的请求地址。</li>
<li>method: String - 推送的请求方法。</li>
<li>header: <a href="#class-httpheaders">HttpHeaders</a> - 推送的请求头。</li>
</ul>
<h2 id="class-httpresponsewriter"><a class="header" href="#class-httpresponsewriter">class HttpResponseWriter</a></h2>
<pre><code class="language-cangjie">public class HttpResponseWriter {
    public HttpResponseWriter(let ctx: HttpContext)
}
</code></pre>
<p>功能：HTTP response 消息体 Writer，支持用户控制消息体的发送过程。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>第一次调用 write 函数时，将立即发送 header 和通过参数传入的 body，此后每次调用 write，发送通过参数传入的 body。
对于 HTTP/1.1，如果设置了 transfer-encoding: chunked，用户每调用一次 write，将发送一个 chunk。
对于 HTTP/2，用户每调用一次 write，将把指定数据封装并发出。</p>
</blockquote>
<h3 id="httpresponsewriterhttpcontext"><a class="header" href="#httpresponsewriterhttpcontext">HttpResponseWriter(HttpContext)</a></h3>
<pre><code class="language-cangjie">public HttpResponseWriter(let ctx: HttpContext)
</code></pre>
<p>功能：构造一个 <a href="http_package_classes.html#class-httpresponsewriter">HttpResponseWriter</a> 实例。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h3 id="func-writearraybyte"><a class="header" href="#func-writearraybyte">func write(Array&lt;Byte&gt;)</a></h3>
<pre><code class="language-cangjie">public func write(buf: Array&lt;Byte&gt;): Unit
</code></pre>
<p>功能：发送 buf 中数据到客户端。</p>
<p>参数：</p>
<ul>
<li>buf: Array&lt;Byte&gt; - 要发送的数据。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 请求方法为 &quot;HEAD&quot; 或响应状态码为 &quot;1XX\204\304&quot;。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 连接关闭。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - response 协议版本为 HTTP/1.0。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 响应连接已升级为 <a href="http_package_classes.html#class-websocket">WebSocket</a>。</li>
</ul>
<h2 id="class-notfoundhandler"><a class="header" href="#class-notfoundhandler">class NotFoundHandler</a></h2>
<pre><code class="language-cangjie">public class NotFoundHandler &lt;: HttpRequestHandler
</code></pre>
<p>功能：便捷的 Http 请求处理器，<code>404 Not Found</code> 处理器。</p>
<p>父类型：</p>
<ul>
<li><a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a></li>
</ul>
<h3 id="func-handlehttpcontext-2"><a class="header" href="#func-handlehttpcontext-2">func handle(HttpContext)</a></h3>
<pre><code class="language-cangjie">public func handle(ctx: HttpContext): Unit
</code></pre>
<p>功能：处理 Http 请求，回复 404 响应。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h2 id="class-optionshandler"><a class="header" href="#class-optionshandler">class OptionsHandler</a></h2>
<pre><code class="language-cangjie">public class OptionsHandler &lt;: HttpRequestHandler
</code></pre>
<p>功能：便捷的 Http 处理器，用于处理 OPTIONS 请求。固定返回 &quot;Allow: OPTIONS，GET，HEAD，POST，PUT，DELETE&quot; 响应头。</p>
<p>父类型：</p>
<ul>
<li><a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a></li>
</ul>
<h3 id="func-handlehttpcontext-3"><a class="header" href="#func-handlehttpcontext-3">func handle(HttpContext)</a></h3>
<pre><code class="language-cangjie">public func handle(ctx: HttpContext): Unit
</code></pre>
<p>功能：处理 Http OPTIONS 请求。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h2 id="class-protocolservice"><a class="header" href="#class-protocolservice">class ProtocolService</a></h2>
<pre><code class="language-cangjie">public abstract class ProtocolService
</code></pre>
<p>功能：Http 协议服务实例，为单个客户端连接提供 Http 服务，包括对客户端 request 报文的解析、 request 的分发处理、 response 的发送等。</p>
<h3 id="prop-server"><a class="header" href="#prop-server">prop server</a></h3>
<pre><code class="language-cangjie">open protected mut prop server: Server
</code></pre>
<p>功能：返回 <a href="#class-server">Server</a> 实例，提供默认实现，设置为绑定的 <a href="#class-server">Server</a> 实例</p>
<h3 id="func-serve"><a class="header" href="#func-serve">func serve()</a></h3>
<pre><code class="language-cangjie">protected func serve(): Unit
</code></pre>
<p>功能：处理来自客户端连接的请求，不提供默认实现。</p>
<h3 id="func-closegracefully"><a class="header" href="#func-closegracefully">func closeGracefully()</a></h3>
<pre><code class="language-cangjie">open protected func closeGracefully(): Unit
</code></pre>
<p>功能：优雅关闭连接，提供默认实现，无任何行为。</p>
<h3 id="func-close-1"><a class="header" href="#func-close-1">func close()</a></h3>
<pre><code class="language-cangjie">open protected func close(): Unit
</code></pre>
<p>功能：强制关闭连接，提供默认实现，无任何行为。</p>
<h2 id="class-redirecthandler"><a class="header" href="#class-redirecthandler">class RedirectHandler</a></h2>
<pre><code class="language-cangjie">public class RedirectHandler &lt;: HttpRequestHandler {
    public init(url: String, code: UInt16)
}
</code></pre>
<p>功能：便捷的 Http 处理器，用于回复重定向响应。</p>
<p>父类型：</p>
<ul>
<li><a href="http_package_interfaces.html#interface-httprequesthandler">HttpRequestHandler</a></li>
</ul>
<h3 id="initstring-uint16"><a class="header" href="#initstring-uint16">init(String, UInt16)</a></h3>
<pre><code class="language-cangjie">public init(url: String, code: UInt16)
</code></pre>
<p>功能：<a href="http_package_classes.html#class-redirecthandler">RedirectHandler</a> 的构造函数。</p>
<p>参数：</p>
<ul>
<li>url: String - 重定向响应中 Location 头部的 url。</li>
<li>code: UInt16 - 重定向响应的响应码。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - url 为空或响应码不是除 304 以外的 3XX 状态码时抛出异常。</li>
</ul>
<h3 id="func-handlehttpcontext-4"><a class="header" href="#func-handlehttpcontext-4">func handle(HttpContext)</a></h3>
<pre><code class="language-cangjie">public func handle(ctx: HttpContext): Unit
</code></pre>
<p>功能：处理 Http 请求，回复重定向响应。</p>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文。</li>
</ul>
<h2 id="class-server"><a class="header" href="#class-server">class Server</a></h2>
<pre><code class="language-cangjie">public class Server
</code></pre>
<p>功能：提供 HTTP 服务的 <a href="http_package_classes.html#class-server">Server</a> 类。</p>
<blockquote>
<p><strong>说明：</strong></p>
<ul>
<li>启动服务，在指定地址及端口等待用户连接、服务用户的 http request；</li>
<li>关闭服务，包括关闭所有已有连接；</li>
<li>提供注册处理 http request 的 handler 的机制，根据注册信息分发 request 到相应的 handler；</li>
<li>提供 tls 证书热机制；</li>
<li>提供 shutdown 回调机制；</li>
<li>通过 <a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a>.level 开启、关闭日志打印，包括按照用户要求打印相应级别的日志；</li>
<li><a href="http_package_classes.html#class-server">Server</a> 文档中未明确说明支持版本的配置，在 HTTP/1.1 与 HTTP/2 都会生效。</li>
</ul>
</blockquote>
<h3 id="prop-addr"><a class="header" href="#prop-addr">prop addr</a></h3>
<pre><code class="language-cangjie">public prop addr: String
</code></pre>
<p>功能：获取服务端监听地址。</p>
<p>类型：String</p>
<h3 id="prop-distributor"><a class="header" href="#prop-distributor">prop distributor</a></h3>
<pre><code class="language-cangjie">public prop distributor: HttpRequestDistributor
</code></pre>
<p>功能：获取请求分发器，请求分发器会根据 url 将请求分发给对应的 handler。</p>
<p>类型：<a href="http_package_interfaces.html#interface-httprequestdistributor">HttpRequestDistributor</a></p>
<h3 id="prop-enableconnectprotocol"><a class="header" href="#prop-enableconnectprotocol">prop enableConnectProtocol</a></h3>
<pre><code class="language-cangjie">public prop enableConnectProtocol: Bool
</code></pre>
<p>功能：HTTP/2 专用，用来限制对端发送的报文是否支持通过 connect 方法升级协议，true 表示支持。</p>
<p>类型：Bool</p>
<h3 id="prop-headertablesize-1"><a class="header" href="#prop-headertablesize-1">prop headerTableSize</a></h3>
<pre><code class="language-cangjie">public prop headerTableSize: UInt32
</code></pre>
<p>功能：获取服务端 HTTP/2 Hpack 动态表的初始值，默认值为 4096。</p>
<p>类型：UInt32</p>
<h3 id="prop-httpkeepalivetimeout"><a class="header" href="#prop-httpkeepalivetimeout">prop httpKeepAliveTimeout</a></h3>
<pre><code class="language-cangjie">public prop httpKeepAliveTimeout: Duration
</code></pre>
<p>功能：HTTP/1.1 专用，获取服务器设定的保持长连接的超时时间。</p>
<p>类型：Duration</p>
<h3 id="prop-initialwindowsize-1"><a class="header" href="#prop-initialwindowsize-1">prop initialWindowSize</a></h3>
<pre><code class="language-cangjie">public prop initialWindowSize: UInt32
</code></pre>
<p>功能：HTTP/2 专用，用来限制对端发送的报文stream 初始流量窗口大小。默认值为 65535 ，取值范围为 0 至 2^31 - 1。</p>
<p>类型：UInt32</p>
<h3 id="prop-listener"><a class="header" href="#prop-listener">prop listener</a></h3>
<pre><code class="language-cangjie">public prop listener: ServerSocket
</code></pre>
<p>功能：获取服务器绑定 socket。</p>
<p>类型：ServerSocket</p>
<h3 id="prop-logger-1"><a class="header" href="#prop-logger-1">prop logger</a></h3>
<pre><code class="language-cangjie">public prop logger: Logger
</code></pre>
<p>功能：获取服务器日志记录器，设置 logger.level 将立即生效，记录器应该是线程安全的。</p>
<p>类型：<a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a></p>
<h3 id="prop-maxconcurrentstreams-1"><a class="header" href="#prop-maxconcurrentstreams-1">prop maxConcurrentStreams</a></h3>
<pre><code class="language-cangjie">public prop maxConcurrentStreams: UInt32
</code></pre>
<p>功能：HTTP/2 专用，用来限制连接同时处理的最大请求数量。</p>
<p>类型：UInt32</p>
<h3 id="prop-maxframesize-1"><a class="header" href="#prop-maxframesize-1">prop maxFrameSize</a></h3>
<pre><code class="language-cangjie">public prop maxFrameSize: UInt32
</code></pre>
<p>功能：HTTP/2 专用，用来限制对端发送的报文一个帧的最大长度。默认值为 16384. 取值范围为 2^14 至 2^24 - 1。</p>
<p>类型：UInt32</p>
<h3 id="prop-maxheaderlistsize-1"><a class="header" href="#prop-maxheaderlistsize-1">prop maxHeaderListSize</a></h3>
<pre><code class="language-cangjie">public prop maxHeaderListSize: UInt32
</code></pre>
<p>功能：获取客户端支持的 HTTP/2 最大头部（Header）大小。这个大小指的是响应头部中所有头部字段（Header Field）的最大允许长度之和，其中包括所有字段名称（name）的长度、字段值（value）的长度以及每个字段自动添加的伪头开销（通常每个字段会有32字节的开销，这包括了HTTP/2协议本身为头部字段添加的伪头部信息）。默认情况下，这个最大长度被设置为 UInt32.Max。</p>
<p>类型：UInt32</p>
<h3 id="prop-maxrequestbodysize"><a class="header" href="#prop-maxrequestbodysize">prop maxRequestBodySize</a></h3>
<pre><code class="language-cangjie">public prop maxRequestBodySize: Int64
</code></pre>
<p>功能：获取服务器设定的读取请求的请求体最大值，仅对于 HTTP/1.1 且未设置 &quot;Transfer-Encoding: chunked&quot; 的请求生效。</p>
<p>类型：Int64</p>
<h3 id="prop-maxrequestheadersize"><a class="header" href="#prop-maxrequestheadersize">prop maxRequestHeaderSize</a></h3>
<pre><code class="language-cangjie">public prop maxRequestHeaderSize: Int64
</code></pre>
<p>功能：获取服务器设定的读取请求的请求头最大值。仅对 HTTP/1.1 生效，HTTP/2 中有专门的配置 maxHeaderListSize。</p>
<p>类型：Int64</p>
<h3 id="prop-port"><a class="header" href="#prop-port">prop port</a></h3>
<pre><code class="language-cangjie">public prop port: UInt16
</code></pre>
<p>功能：获取服务端监听端口。</p>
<p>类型：UInt16</p>
<h3 id="prop-protocolservicefactory"><a class="header" href="#prop-protocolservicefactory">prop protocolServiceFactory</a></h3>
<pre><code class="language-cangjie">public prop protocolServiceFactory: ProtocolServiceFactory
</code></pre>
<p>功能：获取协议服务工厂，服务协议工厂会生成每个协议所需的服务实例。</p>
<p>类型：<a href="http_package_interfaces.html#interface-protocolservicefactory">ProtocolServiceFactory</a></p>
<h3 id="prop-readheadertimeout"><a class="header" href="#prop-readheadertimeout">prop readHeaderTimeout</a></h3>
<pre><code class="language-cangjie">public prop readHeaderTimeout: Duration
</code></pre>
<p>功能：获取服务器设定的读取请求头的超时时间。</p>
<p>类型：Duration</p>
<h3 id="prop-readtimeout-2"><a class="header" href="#prop-readtimeout-2">prop readTimeout</a></h3>
<pre><code class="language-cangjie">public prop readTimeout: Duration
</code></pre>
<p>功能：获取服务器设定的读取整个请求的超时时间。</p>
<p>类型：Duration</p>
<h3 id="prop-servicepoolconfig"><a class="header" href="#prop-servicepoolconfig">prop servicePoolConfig</a></h3>
<pre><code class="language-cangjie">public prop servicePoolConfig: ServicePoolConfig
</code></pre>
<p>功能：获取协程池配置实例。</p>
<p>类型：<a href="http_package_structs.html#struct-servicepoolconfig">ServicePoolConfig</a></p>
<h3 id="prop-transportconfig"><a class="header" href="#prop-transportconfig">prop transportConfig</a></h3>
<pre><code class="language-cangjie">public prop transportConfig: TransportConfig
</code></pre>
<p>功能：获取服务器设定的传输层配置。</p>
<p>类型：<a href="http_package_structs.html#struct-transportconfig">TransportConfig</a></p>
<h3 id="prop-writetimeout-2"><a class="header" href="#prop-writetimeout-2">prop writeTimeout</a></h3>
<pre><code class="language-cangjie">public prop writeTimeout: Duration
</code></pre>
<p>功能：获取服务器设定的写响应的超时时间。</p>
<p>类型：Duration</p>
<h3 id="func-afterbind---unit"><a class="header" href="#func-afterbind---unit">func afterBind(() -&gt; Unit)</a></h3>
<pre><code class="language-cangjie">public func afterBind(f: ()-&gt; Unit): Unit
</code></pre>
<p>功能：注册服务器启动时的回调函数，服务内部 ServerSocket 实例 bind 之后，accept 之前将调用该函数。重复调用将覆盖之前注册的函数。</p>
<p>参数：</p>
<ul>
<li>f: () -&gt; Unit - 回调函数，入参为空，返回值为 Unit 类型。</li>
</ul>
<h3 id="func-close-2"><a class="header" href="#func-close-2">func close()</a></h3>
<pre><code class="language-cangjie">public func close(): Unit
</code></pre>
<p>功能：关闭服务器，服务器关闭后将不再对请求进行读取与处理，重复关闭将只有第一次生效（包括 close 和 closeGracefully）。</p>
<h3 id="func-closegracefully-1"><a class="header" href="#func-closegracefully-1">func closeGracefully()</a></h3>
<pre><code class="language-cangjie">public func closeGracefully(): Unit
</code></pre>
<p>功能：关闭服务器，服务器关闭后将不再对请求进行读取，当前正在进行处理的服务器待处理结束后进行关闭。</p>
<h3 id="func-gettlsconfig-1"><a class="header" href="#func-gettlsconfig-1">func getTlsConfig()</a></h3>
<pre><code class="language-cangjie">public func getTlsConfig(): ?TlsServerConfig
</code></pre>
<p>功能：获取服务器设定的 TLS 层配置。</p>
<p>返回值：</p>
<ul>
<li>?<a href="../../tls/tls_package_api/tls_package_structs.html#struct-tlsclientconfig">TlsServerConfig</a> - 服务端设定的 TLS 层配置，如果没有设置则返回 None。</li>
</ul>
<h3 id="func-onshutdown---unit"><a class="header" href="#func-onshutdown---unit">func onShutdown(() -&gt; Unit)</a></h3>
<pre><code class="language-cangjie">public func onShutdown(f: () -&gt; Unit): Unit
</code></pre>
<p>功能：注册服务器关闭时的回调函数，服务器关闭时将调用该回调函数，重复调用将覆盖之前注册的函数。</p>
<p>参数：</p>
<ul>
<li>f: () -&gt; Unit - 回调函数，入参为空，返回值为 Unit 类型。</li>
</ul>
<h3 id="func-serve-1"><a class="header" href="#func-serve-1">func serve()</a></h3>
<pre><code class="language-cangjie">public func serve(): Unit
</code></pre>
<p>功能：启动服务端进程，不支持重复启动。</p>
<p>h1 request 检查和处理：</p>
<ul>
<li>request-line 不符合 RFC 9112 中 request-line = method SP request-target SP HTTP-version 的规则，将会返回 400 响应；</li>
<li>method 由 tokens 组成，且大小写敏感；request-target 为能够被解析的 url；HTTP-version 为 HTTP/1.0 或 HTTP/1.1 ，否则将会返回 400 响应；</li>
<li>headers name 和 value 需符合特定规则，详见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类说明，否则返回 400 响应；</li>
<li>当 headers 的大小超出 server 设定的 maxRequestHeaderSize 时将自动返回 431 响应；</li>
<li>headers 中必须包含 &quot;host&quot; 请求头，且值唯一，否则返回 400 响应headers 中不允许同时存在 &quot;content-length&quot; 与 &quot;transfer-encoding&quot; 请求头，否则返回 400 响应；</li>
<li>请求头 &quot;transfer-encoding&quot; 的 value 经过 &quot;,&quot; 分割后最后一个 value 必须为 &quot;chunked&quot;，且之前的 value 不允许存在 &quot;chunked&quot;，否则返回 400 响应；</li>
<li>请求头 &quot;content-length&quot; 其 value 必须能解析为 Int64 类型，且不能为负值，否则返回 400 响应，当其 value 值超出 server 设定maxRequestBodySize，将返回 413 响应；</li>
<li>headers 中若不存在 &quot;content-length&quot; 和 &quot;transfer-encoding: chunked&quot; 时默认不存在 body；</li>
<li>请求头 &quot;trailer&quot; 中，value 不允许存在 &quot;transfer-encoding&quot;，&quot;trailer&quot;，&quot;content-length&quot;；</li>
<li>请求头 &quot;expect&quot; 中，value 中存在非 &quot;100-continue&quot; 的值，将会返回 417 响应；</li>
<li>HTTP/1.0 默认短连接，若想保持长连接需要包含请求头 &quot;connection: keep-alive&quot; 与 &quot;keep-alive: timeout = XX, max = XX&quot;，将会自动保持 timeout 时长的连接。HTTP/1.1 默认长连接，当解析 request 失败则关闭连接；</li>
<li>仅允许在 chunked 模式下存在 trailer，且 trailer 中条目的 name 必须被包含在 &quot;trailer&quot; 请求头中，否则将自动删除。</li>
</ul>
<p>h1 response 检查和处理：</p>
<ul>
<li>若用户不对 response 进行配置，将会自动返回 200 响应；</li>
<li>若接收到的 request 包含请求头 &quot;connection: close&quot; 而配置 response 未添加响应头 &quot;connection&quot; 或响应头 &quot;connection&quot; 的 value 不包含 &quot;close&quot;，将自动添加 &quot;connection: close&quot;，若接收到的 request 不包含请求头 &quot;connection: close&quot; 且响应头不存在 &quot;connection: keep-alive&quot;，将会自动添加；</li>
<li>如果 headers 包含逐跳响应头：&quot;proxy-connection&quot;，&quot;keep-alive&quot;，&quot;te&quot;，&quot;transfer-encoding&quot;，&quot;upgrade&quot;，将会在响应头 &quot;connection&quot; 自动添加这些头作为 value；</li>
<li>将自动添加 &quot;date&quot; 响应头，用户提供的 &quot;date&quot; 将被忽略；</li>
<li>若请求方法为 &quot;HEAD&quot; 或响应状态码为 &quot;1XX\204\304&quot;，body将配置为空；</li>
<li>若已知提供 body 的长度时，将会与响应头 &quot;content-length&quot; 进行比较，若不存在响应头 &quot;content-length&quot;，将自动添加此响应头，其 value 值为 body 长度。若响应头 &quot;content-length&quot; 长度大于 body 长度，将会在 handler 中抛出 <a href="http_package_exceptions.html#class-httpexception">HttpException</a>，若小于 body 长度，将对 body 进行截断处理，发送的 body 长度将为 &quot;content-length&quot; 的值；</li>
<li>response 中 &quot;set-cookie&quot; header 将分条发送，其他 headers 同名条目将合成一条发送；</li>
<li>在处理包含请求头：&quot;expect: 100-continue&quot; 的 request 时，在调用 request 的 body.read() 时将会自动发送状态码为 100 的响应给客户端。不允许用户主动发送状态码为 100 的 response，若进行发送则被认定为服务器异常。</li>
</ul>
<p>启用 h2 服务：tlsConfig 中 supportedAlpnProtocols 需包含 &quot;h2&quot;，此后如果 tls 层 alpn 协商结果为 h2，则启用 h2 服务。</p>
<p>h2 request 检查和处理：</p>
<ul>
<li>headers name 和 value 需符合特定规则，详见 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 类说明，此外 name 不能包含大写字符，否则发送 RST 帧关闭流，即无法保证返回响应；</li>
<li>trailers name 和 value 需符合同样规则，否则关闭流；</li>
<li>headers 不能包含 &quot;connection&quot;，&quot;transfer-encoding&quot;，&quot;keep-alive&quot;，&quot;upgrade&quot;，&quot;proxy-connection&quot;，否则关闭流；</li>
<li>如果有 &quot;te&quot; header，其值只能为 &quot;trailers&quot;，否则关闭流；</li>
<li>如果有 &quot;host&quot; header 和 &quot;:authority&quot; pseudo header，&quot;host&quot; 值必须与 &quot;:authority&quot; 一致，否则关闭流；</li>
<li>如果有 &quot;content-length&quot; header，需符合 &quot;content-length&quot; 每个值都能解析为 Int64 类型，且如果有多个值，必须相等，否则关闭流；</li>
<li>如果有 &quot;content-length&quot; header，且有 body 大小，则 content-length 值与 body 大小必须相等，否则关闭流；</li>
<li>如果有 &quot;trailer&quot; header，其值不能包含 &quot;transfer-encoding&quot;，&quot;trailer&quot;，&quot;content-length&quot;，否则关闭流；</li>
<li>仅在升级 <a href="http_package_classes.html#class-websocket">WebSocket</a> 场景下支持 CONNECT 方法，否则关闭流；</li>
<li>pseudo headers 中，必须包含 &quot;:method&quot;、&quot;:scheme&quot;、&quot;:path&quot;，其中 &quot;:method&quot; 值必须由 tokens 字符组成，&quot;:scheme&quot; 值必须为 &quot;https&quot;，&quot;:path&quot; 不能为空，否则关闭流；</li>
<li>trailer 中条目的 name 必须被包含在 &quot;trailer&quot; 头中，否则将自动删除；</li>
<li>request headers 大小不能超过 maxHeaderListSize，否则关闭连接。</li>
</ul>
<p>h2 response 检查和处理：</p>
<ul>
<li>如果 HEAD 请求的响应包含 body，将自动删除；</li>
<li>将自动添加 &quot;date&quot; field，用户提供的 &quot;date&quot; 将被忽略；</li>
<li>如果 headers 包含 &quot;connection&quot;，&quot;transfer-encoding&quot;，&quot;keep-alive&quot;，&quot;upgrade&quot;，&quot;proxy-connection&quot;，将自动删除；</li>
<li>response 中 &quot;set-cookie&quot; header 将分条发送，其他 headers 同名条目将合成一条发送；</li>
<li>如果 headers 包含 &quot;content-length&quot;，且 method 不为 &quot;HEAD&quot;，&quot;content-length&quot; 将被删除；</li>
<li>如果 method 为 &quot;HEAD&quot;，则：
<ul>
<li>headers 包含 &quot;content-length&quot;，但 &quot;content-length&quot; 不合法（无法被解析为 Int64 值，或包含多个不同值），如果用户调用 <a href="http_package_classes.html#class-httpresponsewriter">HttpResponseWriter</a> 类的 write 函数，将抛出 <a href="http_package_exceptions.html#class-httpexception">HttpException</a>，如果用户 handler 已经结束，将打印日志；</li>
<li>headers 包含 &quot;content-length&quot;，同时 response.body.length 不为 -1，&quot;content-length&quot; 值与 body.length 不符，同 6.1 处理；</li>
<li>headers 包含 &quot;content-length&quot;，同时 response.body.length 为 -1，或 body.length 与 &quot;content-length&quot; 值一致，则保留 &quot;content-length&quot; header；</li>
</ul>
</li>
<li>trailer 中条目必须被包含在 &quot;trailer&quot; 头中，否则将自动删除；</li>
<li>如果 handler 中抛出异常，且用户未调用 write 发送部分响应，将返回 500 响应。如果用户已经调用 write 发送部分响应，将发送 RST 帧关闭 stream。</li>
</ul>
<p>h2 server 发完 response 之后，如果 stream 状态不是 CLOSED，会发送带 NO_ERROR 错误码的 RST 帧关闭 stream，避免已经处理完毕的 stream 继续占用服务器资源。</p>
<p>h2 流量控制：</p>
<ul>
<li>connection 流量窗口初始值为 65535，每次收到 DATA 帧将返回一个 connection 层面的 WINDOW-UPDATE，发送 DATA 时，如果 connection 流量窗口值为负数，将阻塞至其变为正数；</li>
<li>stream 流量窗口初始值可由用户设置，默认值为 65535，每次收到 DATA 帧将返回一个 stream 层面的 WINDOW-UPDATE，发送 DATA 时，如果 stream 流量窗口值为负数，将阻塞至其变为正数。</li>
</ul>
<p>h2 请求优先级：</p>
<ul>
<li>支持按 urgency 处理请求，h2 服务默认并发处理请求，当并发资源不足时，请求将按 urgency 处理，优先级高的请求优先处理。</li>
</ul>
<p>默认 <a href="http_package_interfaces.html#interface-protocolservicefactory">ProtocolServiceFactory</a> 协议选择：</p>
<ul>
<li>如果连接是 tcp，使用 HTTP/1.1 server；</li>
<li>如果连接是 tls，根据 alpn 协商结果确定 http 协议版本，如果协商结果为 &quot;http/1.0&quot;，&quot;http/1.1&quot; 或 &quot;&quot;，使用 HTTP/1.1 server，如果协商结果为 &quot;h2&quot;，使用 HTTP/2 server，否则不处理此次请求，打印日志关连接。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 当端口监听失败时，抛出异常。</li>
</ul>
<h3 id="func-updatecaarrayx509certificate"><a class="header" href="#func-updatecaarrayx509certificate">func updateCA(Array&lt;X509Certificate&gt;)</a></h3>
<pre><code class="language-cangjie">public func updateCA(newCa: Array&lt;X509Certificate&gt;): Unit
</code></pre>
<p>功能：对 CA 证书进行热更新。</p>
<p>参数：</p>
<ul>
<li>newCa: Array&lt;<a href="../../../crypto/x509/x509_package_api/x509_package_classes.html#class-x509certificate">X509Certificate</a>&gt; - CA证书。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 参数包含空字符时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 服务端未配置 tlsConfig时抛出异常。</li>
</ul>
<h3 id="func-updatecastring"><a class="header" href="#func-updatecastring">func updateCA(String)</a></h3>
<pre><code class="language-cangjie">public func updateCA(newCaFile: String): Unit
</code></pre>
<p>功能：对 CA 证书进行热更新。</p>
<p>参数：</p>
<ul>
<li>newCaFile: String - CA证书文件。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 参数包含空字符时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 服务端未配置 tlsConfig时抛出异常。</li>
</ul>
<h3 id="func-updatecertarrayx509certificate-privatekey"><a class="header" href="#func-updatecertarrayx509certificate-privatekey">func updateCert(Array&lt;X509Certificate&gt;, PrivateKey)</a></h3>
<pre><code class="language-cangjie">public func updateCert(certChain: Array&lt;X509Certificate&gt;, certKey: PrivateKey): Unit
</code></pre>
<p>功能：对 TLS 证书进行热更新。</p>
<p>参数：</p>
<ul>
<li>certChain: Array&lt;<a href="../../../crypto/x509/x509_package_api/x509_package_classes.html#class-x509certificate">X509Certificate</a>&gt; - 证书链。</li>
<li>certKey: <a href="../../../crypto/x509/x509_package_api/x509_package_interfaces.html#interface-privatekey">PrivateKey</a> - 证书匹配的私钥。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 服务端未配置 tlsConfig时抛出异常。</li>
</ul>
<h3 id="func-updatecertstring-string"><a class="header" href="#func-updatecertstring-string">func updateCert(String, String)</a></h3>
<pre><code class="language-cangjie">public func updateCert(certificateChainFile: String, privateKeyFile: String): Unit
</code></pre>
<p>功能：对 TLS 证书进行热更新。</p>
<p>参数：</p>
<ul>
<li>certificateChainFile: String - 证书链文件。</li>
<li>privateKeyFile: String - 证书匹配的私钥文件。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 参数包含空字符时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 服务端未配置 tlsConfig时抛出异常。</li>
</ul>
<h2 id="class-serverbuilder"><a class="header" href="#class-serverbuilder">class ServerBuilder</a></h2>
<pre><code class="language-cangjie">public class ServerBuilder {
    public init()
}
</code></pre>
<p>功能：提供 <a href="http_package_classes.html#class-server">Server</a> 实例构建器。</p>
<p>支持通过如下参数构造一个 Http <a href="http_package_classes.html#class-server">Server</a>：</p>
<ul>
<li>地址、端口；</li>
<li>线程安全的 logger；</li>
<li><a href="http_package_interfaces.html#interface-httprequestdistributor">HttpRequestDistributor</a>，用于注册 handler、分发 request；</li>
<li>HTTP/2 的 settings；</li>
<li>shutdown 回调；</li>
<li>transport：listener、连接及其配置；</li>
<li>protocol service：http 协议解析服务；</li>
</ul>
<p>除地址端口、shutdown 回调外，均提供默认实现，用户在构造 server 过程中可不指定其他构建参数。
<a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 文档中未明确说明支持版本的配置，在 HTTP/1.1 与 HTTP/2 都会生效。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>该类提供了一系列配置参数的函数，配置完成后调用 <a href="./http_package_classes.html#func-build-3">build</a> 函数构造出 <a href="./http_package_classes.html#class-server">Server</a> 实例。配置函数中说明了参数的取值范围，但配置函数本身不做参数合法性校验，<a href="./http_package_classes.html#func-build-3">build</a> 时统一进行校验。</p>
</blockquote>
<h3 id="init-3"><a class="header" href="#init-3">init()</a></h3>
<pre><code class="language-cangjie">public init()
</code></pre>
<p>功能：创建 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 实例。</p>
<h3 id="func-addrstring"><a class="header" href="#func-addrstring">func addr(String)</a></h3>
<pre><code class="language-cangjie">public func addr(addr: String): ServerBuilder
</code></pre>
<p>功能：设置服务端监听地址，若 listener 被设定，此值被忽略。</p>
<p>格式需符合 IPAddress 中相关规定。</p>
<p>参数：</p>
<ul>
<li>addr: String - 地址值。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-afterbind-unit"><a class="header" href="#func-afterbind-unit">func afterBind(()-&gt;Unit)</a></h3>
<pre><code class="language-cangjie">public func afterBind(f: ()-&gt;Unit): ServerBuilder
</code></pre>
<p>功能：注册服务器启动时的回调函数，服务内部 ServerSocket 实例 bind 之后，accept 之前将调用该函数。重复调用将覆盖之前注册的函数。</p>
<p>参数：</p>
<ul>
<li>f: () -&gt;Unit - 回调函数，入参为空，返回值为 Unit 类型。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-build-3"><a class="header" href="#func-build-3">func build()</a></h3>
<pre><code class="language-cangjie">public func build(): Server
</code></pre>
<p>功能：根据设置的参数构建 <a href="http_package_classes.html#class-server">Server</a> 实例。</p>
<p>此处会对各参数的值进行检查，如果取值非法，将抛出异常。各参数的取值范围详见设置参数相关的函数。</p>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-server">Server</a> - 生成的 <a href="http_package_classes.html#class-server">Server</a> 实例。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 当设置的参数非法时，抛出异常。</li>
<li>IllegalFormatException 格式错误时，抛出异常。</li>
</ul>
<h3 id="func-distributorhttprequestdistributor"><a class="header" href="#func-distributorhttprequestdistributor">func distributor(HttpRequestDistributor)</a></h3>
<pre><code class="language-cangjie">public func distributor(distributor: HttpRequestDistributor): ServerBuilder
</code></pre>
<p>功能：设置请求分发器，请求分发器会根据 url 将请求分发给对应的 handler。不设置时使用默认请求分发器。</p>
<p>参数：</p>
<ul>
<li>distributor: <a href="http_package_interfaces.html#interface-httprequestdistributor">HttpRequestDistributor</a> - 自定义请求分发器实例。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-enableconnectprotocolbool"><a class="header" href="#func-enableconnectprotocolbool">func enableConnectProtocol(Bool)</a></h3>
<pre><code class="language-cangjie">public func enableConnectProtocol(flag: Bool): ServerBuilder
</code></pre>
<p>功能：HTTP/2 专用，设置本端是否接收 CONNECT 请求，默认 false。</p>
<p>参数：</p>
<ul>
<li>flag: Bool - 本端是否接收 CONNECT 请求。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-headertablesizeuint32-1"><a class="header" href="#func-headertablesizeuint32-1">func headerTableSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func headerTableSize(size: UInt32): ServerBuilder
</code></pre>
<p>功能：设置服务端 HTTP/2 Hpack 动态表的初始值，默认值为 4096。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 本端对响应头编码时使用的最大 <code>table size</code></li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-httpkeepalivetimeoutduration"><a class="header" href="#func-httpkeepalivetimeoutduration">func httpKeepAliveTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func httpKeepAliveTimeout(timeout: Duration): ServerBuilder
</code></pre>
<p>功能：HTTP/1.1 专用，设定服务端连接保活时长，该时长内客户端未再次发送请求，服务端将关闭长连接，默认不进行限制。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 设定保持长连接的超时时间，如果传入负的 Duration 将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-initialwindowsizeuint32-1"><a class="header" href="#func-initialwindowsizeuint32-1">func initialWindowSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func initialWindowSize(size: UInt32): ServerBuilder
</code></pre>
<p>功能：HTTP/2 专用，设置当前服务器上每个流的接收报文的初始流量窗口大小，默认值为 65535。取值范围为 0 至 2^31 - 1。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 本端一个 stream 上接收报文的初始流量窗口大小。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-listenerserversocket"><a class="header" href="#func-listenerserversocket">func listener(ServerSocket)</a></h3>
<pre><code class="language-cangjie">public func listener(listener: ServerSocket): ServerBuilder
</code></pre>
<p>功能：服务端调用此函数对指定 socket 进行绑定监听。</p>
<p>参数：</p>
<ul>
<li>listener: ServerSocket - 所绑定的socket。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-loggerlogger-1"><a class="header" href="#func-loggerlogger-1">func logger(Logger)</a></h3>
<pre><code class="language-cangjie">public func logger(logger: Logger): ServerBuilder
</code></pre>
<p>功能：设定服务器的 logger，默认 logger 级别为 INFO，logger 内容将写入 Console.stdout。</p>
<p>参数：</p>
<ul>
<li>logger: <a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a> - 需要是线程安全的，默认使用内置线程安全 logger。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-maxconcurrentstreamsuint32-1"><a class="header" href="#func-maxconcurrentstreamsuint32-1">func maxConcurrentStreams(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxConcurrentStreams(size: UInt32): ServerBuilder
</code></pre>
<p>功能：HTTP/2 专用，设置本端同时处理的最大请求数量，限制对端并发发送请求的数量，默认值为 100。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 本端同时处理的最大请求数量。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-maxframesizeuint32-1"><a class="header" href="#func-maxframesizeuint32-1">func maxFrameSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxFrameSize(size: UInt32): ServerBuilder
</code></pre>
<p>功能：HTTP/2 专用，设置本端接收的一个帧的最大长度，用来限制对端发送帧的长度，默认值为 16384. 取值范围为 2^14 至 2^24 - 1。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 本端接收的一个帧的最大长度。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-maxheaderlistsizeuint32-1"><a class="header" href="#func-maxheaderlistsizeuint32-1">func maxHeaderListSize(UInt32)</a></h3>
<pre><code class="language-cangjie">public func maxHeaderListSize(size: UInt32): ServerBuilder
</code></pre>
<p>功能：获取客户端支持的 HTTP/2 最大头部（Header）大小。这个大小指的是响应头部中所有头部字段（Header Field）的最大允许长度之和，其中包括所有字段名称（name）的长度、字段值（value）的长度以及每个字段自动添加的伪头开销（通常每个字段会有32字节的开销，这包括了 HTTP/2 协议本身为头部字段添加的伪头部信息）。默认情况下，这个最大长度被设置为 UInt32.Max。</p>
<p>参数：</p>
<ul>
<li>size: UInt32 - 本端接收的报文头最大长度。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-maxrequestbodysizeint64"><a class="header" href="#func-maxrequestbodysizeint64">func maxRequestBodySize(Int64)</a></h3>
<pre><code class="language-cangjie">public func maxRequestBodySize(size: Int64): ServerBuilder
</code></pre>
<p>功能：设置服务端允许客户端发送单个请求的请求体最大长度，请求体长度超过该值时，将返回状态码为 413 的响应。默认值为 2M。仅对于 HTTP/1.1 且未设置 &quot;Transfer-Encoding: chunked&quot; 的请求生效。</p>
<p>参数：</p>
<ul>
<li>size: Int64 - 设定允许接收请求的请求体大小最大值，值为 0 代表不作限制。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 当入参size &lt; 0时，抛出异常。</li>
</ul>
<h3 id="func-maxrequestheadersizeint64"><a class="header" href="#func-maxrequestheadersizeint64">func maxRequestHeaderSize(Int64)</a></h3>
<pre><code class="language-cangjie">public func maxRequestHeaderSize(size: Int64): ServerBuilder
</code></pre>
<p>功能：设定服务端允许客户端发送单个请求的请求头最大长度，请求头长度超过该值时，将返回状态码为 431 的响应；仅对 HTTP/1.1 生效，HTTP/2 中有专门的配置 maxHeaderListSize。</p>
<p>参数：</p>
<ul>
<li>size: Int64 - 设定允许接收请求的请求头大小最大值，值为 0 代表不作限制。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<p>异常：</p>
<ul>
<li>IllegalArgumentException - 当入参size &lt; 0时，抛出异常。</li>
</ul>
<h3 id="func-onshutdown---unit-1"><a class="header" href="#func-onshutdown---unit-1">func onShutdown(() -&gt; Unit)</a></h3>
<pre><code class="language-cangjie">public func onShutdown(f: () -&gt; Unit): ServerBuilder
</code></pre>
<p>功能：注册服务器关闭时的回调函数，服务器关闭时将调用该回调函数，重复调用将覆盖之前注册的函数。</p>
<p>参数：</p>
<ul>
<li>f: () -&gt;Unit - 回调函数，入参为空，返回值为 Unit 类型。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-portuint16"><a class="header" href="#func-portuint16">func port(UInt16)</a></h3>
<pre><code class="language-cangjie">public func port(port: UInt16): ServerBuilder
</code></pre>
<p>功能：设置服务端监听端口，若 listener 被设定，此值被忽略。</p>
<p>参数：</p>
<ul>
<li>port: UInt16 - 端口值。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-protocolservicefactoryprotocolservicefactory"><a class="header" href="#func-protocolservicefactoryprotocolservicefactory">func protocolServiceFactory(ProtocolServiceFactory)</a></h3>
<pre><code class="language-cangjie">public func protocolServiceFactory(factory: ProtocolServiceFactory): ServerBuilder
</code></pre>
<p>功能：设置协议服务工厂，服务协议工厂会生成每个协议所需的服务实例，不设置时使用默认工厂。</p>
<p>参数：</p>
<ul>
<li>factory: <a href="http_package_interfaces.html#interface-protocolservicefactory">ProtocolServiceFactory</a> - 自定义工厂实例。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-readheadertimeoutduration"><a class="header" href="#func-readheadertimeoutduration">func readHeaderTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func readHeaderTimeout(timeout: Duration): ServerBuilder
</code></pre>
<p>功能：设定服务端读取客户端发送一个请求的请求头最大时长，超过该时长将不再进行读取并关闭连接，默认不进行限制。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 设定的读请求头超时时间，如果传入负的 Duration 将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-readtimeoutduration-2"><a class="header" href="#func-readtimeoutduration-2">func readTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func readTimeout(timeout: Duration): ServerBuilder
</code></pre>
<p>功能：设定服务端读取一个请求的最大时长，超过该时长将不再进行读取并关闭连接，默认不进行限制。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 设定读请求的超时时间，如果传入时间为负值将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-servicepoolconfigservicepoolconfig"><a class="header" href="#func-servicepoolconfigservicepoolconfig">func servicePoolConfig(ServicePoolConfig)</a></h3>
<pre><code class="language-cangjie">public func servicePoolConfig(cfg: ServicePoolConfig): ServerBuilder
</code></pre>
<p>功能：服务过程中使用的协程池相关设置，具体说明见 <a href="http_package_structs.html#struct-servicepoolconfig">ServicePoolConfig</a> 结构体。</p>
<p>参数：</p>
<ul>
<li>cfg: <a href="http_package_structs.html#struct-servicepoolconfig">ServicePoolConfig</a> - 协程池相关设置。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-tlsconfigtlsserverconfig"><a class="header" href="#func-tlsconfigtlsserverconfig">func tlsConfig(TlsServerConfig)</a></h3>
<pre><code class="language-cangjie">public func tlsConfig(config: TlsServerConfig): ServerBuilder
</code></pre>
<p>功能：设置 TLS 层配置，默认不对其进行设置。</p>
<p>参数：</p>
<ul>
<li>config: <a href="../../tls/tls_package_api/tls_package_structs.html#struct-tlsserverconfig">TlsServerConfig</a> - 设定支持 tls 服务所需要的配置信息。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-transportconfigtransportconfig"><a class="header" href="#func-transportconfigtransportconfig">func transportConfig(TransportConfig)</a></h3>
<pre><code class="language-cangjie">public func transportConfig(config: TransportConfig): ServerBuilder
</code></pre>
<p>功能：设置传输层配置，默认配置详见 <a href="http_package_structs.html#struct-transportconfig">TransportConfig</a> 结构体说明。</p>
<p>参数：</p>
<ul>
<li>config: <a href="http_package_structs.html#struct-transportconfig">TransportConfig</a> - 设定的传输层配置信息。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h3 id="func-writetimeoutduration-2"><a class="header" href="#func-writetimeoutduration-2">func writeTimeout(Duration)</a></h3>
<pre><code class="language-cangjie">public func writeTimeout(timeout: Duration): ServerBuilder
</code></pre>
<p>功能：设定服务端发送一个响应的最大时长，超过该时长将不再进行写入并关闭连接，默认不进行限制。</p>
<p>参数：</p>
<ul>
<li>timeout: Duration - 设定写响应的超时时间，如果传入时间为负值将被替换为 Duration.Zero。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> - 当前 <a href="http_package_classes.html#class-serverbuilder">ServerBuilder</a> 的引用。</li>
</ul>
<h2 id="class-websocket"><a class="header" href="#class-websocket">class WebSocket</a></h2>
<pre><code class="language-cangjie">public class WebSocket
</code></pre>
<p>功能：提供 <a href="http_package_classes.html#class-websocket">WebSocket</a> 服务的相关类，提供 <a href="http_package_classes.html#class-websocket">WebSocket</a> 连接的读、写、关闭等函数。用户通过 upgradeFrom 函数以获取 <a href="http_package_classes.html#class-websocket">WebSocket</a> 连接。</p>
<ul>
<li>调用 <code>read()</code> 读取一个 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a>，用户可通过 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a>.frameType 来知晓帧的类型，通过 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a>.fin 来知晓是否是分段帧。</li>
<li>调用 <code>write(frameType: WebSocketFrameType, byteArray: Array&lt;UInt8&gt;)</code>，传入 message 的类型和 message 的 byte 来发送 <a href="http_package_classes.html#class-websocket">WebSocket</a> 信息，如果写的是控制帧，则不会分段发送，如果写的是数据帧（Text、Binary），则会将 message 按底层 buffer 的大小分段（分成多个 fragment）发送。</li>
</ul>
<p>详细说明见下文接口说明，接口行为以 RFC 6455 为准。</p>
<h3 id="prop-logger-2"><a class="header" href="#prop-logger-2">prop logger</a></h3>
<pre><code class="language-cangjie">public prop logger: Logger
</code></pre>
<p>功能：日志记录器。</p>
<p>类型：<a href="../../../log/log_package_api/log_package_classes.html#class-logger">Logger</a></p>
<h3 id="prop-subprotocol"><a class="header" href="#prop-subprotocol">prop subProtocol</a></h3>
<pre><code class="language-cangjie">public prop subProtocol: String
</code></pre>
<p>功能：获取与对端协商到的 subProtocol，协商时，客户端提供一个按偏好排名的 subProtocols 列表，服务器从中选取一个或零个子协议。</p>
<p>类型：String</p>
<h3 id="static-func-upgradefromclientclient-url-protocol-arrayliststring-httpheaders"><a class="header" href="#static-func-upgradefromclientclient-url-protocol-arrayliststring-httpheaders">static func upgradeFromClient(Client, URL, Protocol, ArrayList&lt;String&gt;, HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public static func upgradeFromClient(client: Client, url: URL,
 version!: Protocol = HTTP1_1,
 subProtocols!: ArrayList&lt;String&gt; = ArrayList&lt;String&gt;(), 
 headers!: HttpHeaders = HttpHeaders()): (WebSocket, HttpHeaders)
</code></pre>
<p>功能：提供客户端升级到 <a href="http_package_classes.html#class-websocket">WebSocket</a> 协议的函数。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>客户端的升级流程为：传入 client 对象，url 对象，构建升级请求，请求服务器后验证其响应，如果握手成功，则返回 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象用于 <a href="http_package_classes.html#class-websocket">WebSocket</a> 通讯，并返回 101 响应头的 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 对象给用户。暂不支持 extensions。如果子协议协商成功，用户可通过调用返回的 <a href="http_package_classes.html#class-websocket">WebSocket</a> 的 subProtocol 查看子协议。</p>
</blockquote>
<p>参数：</p>
<ul>
<li>client: <a href="http_package_classes.html#class-client">Client</a> - 用于请求的 client 对象。</li>
<li>url: <a href="../../../encoding/url/url_package_api/url_package_classes.html#class-url">URL</a> - 用于请求的 url 对象，<a href="http_package_classes.html#class-websocket">WebSocket</a> 升级时要注意 url 的 scheme 为 ws 或 wss。</li>
<li>version!: <a href="http_package_enums.html#enum-protocol">Protocol</a> - 创建 socket 使用的 HTTP 版本，只支持  <a href="./http_package_enums.html#enum-Protocol">HTTP1_1</a> 和  <a href="./http_package_enums.html#enum-Protocol">HTTP2_0</a> 向 <a href="http_package_classes.html#class-websocket">WebSocket</a> 升级。</li>
<li>subProtocols!: ArrayList&lt;String&gt; - 用户配置的子协议列表，按偏好排名，默认为空。若用户配置了，则会随着升级请求发送给服务器。</li>
<li>headers!: <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 需要随着升级请求一同发送的非升级必要头，如 cookie 等。</li>
</ul>
<p>返回值：</p>
<ul>
<li>(<a href="http_package_classes.html#class-websocket">WebSocket</a>, HttpHeaders) - 升级成功，则返回 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象用于通讯和 101 响应的头。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 底层连接错误时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-httpexception">HttpException</a> - 握手时 HTTP 请求过程中出现错误时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 升级失败，升级响应验证不通过时抛出异常。</li>
</ul>
<h3 id="static-func-upgradefromserverhttpcontext-arrayliststring-arrayliststring-httprequest---httpheaders"><a class="header" href="#static-func-upgradefromserverhttpcontext-arrayliststring-arrayliststring-httprequest---httpheaders">static func upgradeFromServer(HttpContext, ArrayList&lt;String&gt;, ArrayList&lt;String&gt;, (HttpRequest) -&gt; HttpHeaders)</a></h3>
<pre><code class="language-cangjie">public static func upgradeFromServer(ctx: HttpContext, subProtocols!: ArrayList&lt;String&gt; = ArrayList&lt;String&gt;(), 
                                        origins!: ArrayList&lt;String&gt; = ArrayList&lt;String&gt;(), 
                                        userFunc!:(HttpRequest) -&gt; HttpHeaders = {_: HttpRequest =&gt; HttpHeaders()}): WebSocket
</code></pre>
<p>功能：提供服务端升级到 <a href="http_package_classes.html#class-websocket">WebSocket</a> 协议的函数，通常在 handler 中使用。</p>
<p>服务端升级的流程为：收到客户端发来的升级请求，验证请求，如果验证通过，则回复 101 响应并返回 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象用于 <a href="http_package_classes.html#class-websocket">WebSocket</a> 通讯。</p>
<ul>
<li>用户通过 subProtocols，origins 参数来配置其支持的 subprotocol 和 origin 白名单，subProtocols如果不设置，则表示不支持子协议，origins 如果不设置，则表示接受所有 origin 的握手请求；</li>
<li>用户通过 userFunc 来自定义处理升级请求的行为，如处理 cookie 等，传入的 userFunc 要求返回一个 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> 对象，其会通过 101 响应回给客户端（升级失败的请求则不会）；</li>
<li>暂不支持 <a href="http_package_classes.html#class-websocket">WebSocket</a> 的 extensions，因此如果握手过程中出现 extensions 协商则会抛 <a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a>；</li>
<li>只支持 HTTP1_1 和 HTTP2_0 向 <a href="http_package_classes.html#class-websocket">WebSocket</a> 升级。</li>
</ul>
<p>参数：</p>
<ul>
<li>ctx: <a href="http_package_classes.html#class-httpcontext">HttpContext</a> - Http 请求上下文，将传入给 handler 的直接传给 upgradeFromServer 即可。</li>
<li>subProtocols!: ArrayList&lt;String&gt; - 用户配置的子协议列表，默认值为空，表示不支持。如果用户配置了，则会选取升级请求中最靠前的作为升级后的 <a href="http_package_classes.html#class-websocket">WebSocket</a> 的子协议，用户可通过调用返回的 <a href="http_package_classes.html#class-websocket">WebSocket</a> 的 subProtocol 查看子协议。</li>
<li>origins!: ArrayList&lt;String&gt; - 用户配置的同意握手的 origin 的白名单，如果不配置，则同意来自所有 origin 的握手，如果配置了，则只接受来自配置 origin 的握手。</li>
<li>userFunc!: (<a href="http_package_classes.html#class-httprequest">HttpRequest</a>) -&gt;<a href="http_package_classes.html#class-httpheaders">HttpHeaders</a> - 用户配置的自定义处理升级请求的函数，该函数返回一个 <a href="http_package_classes.html#class-httpheaders">HttpHeaders</a>。</li>
</ul>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-websocket">WebSocket</a> - 升级得到的 <a href="http_package_classes.html#class-websocket">WebSocket</a> 实例。</li>
</ul>
<h3 id="func-closeconn"><a class="header" href="#func-closeconn">func closeConn()</a></h3>
<pre><code class="language-cangjie">public func closeConn(): Unit
</code></pre>
<p>功能：提供关闭底层 <a href="http_package_classes.html#class-websocket">WebSocket</a> 连接的函数。</p>
<blockquote>
<p><strong>说明：</strong></p>
<p>直接关闭底层连接。正常的关闭流程需要遵循协议规定的握手流程，即先发送 Close 帧给对端，并等待对端回应的 Close 帧。握手流程结束后方可关闭底层连接。</p>
</blockquote>
<h3 id="func-read"><a class="header" href="#func-read">func read()</a></h3>
<pre><code class="language-cangjie">public func read(): WebSocketFrame
</code></pre>
<p>功能：从连接中读取一个帧，如果连接上数据未就绪会阻塞，非线程安全（即对同一个 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象不支持多线程读）。</p>
<p>read 函数返回一个 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 对象，用户可以调用 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 的 frameType，fin 属性确定其帧类型和是否是分段帧调用。通过 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 的 payload 函数得到原始二进制数据数组：Array&lt;UInt8&gt;</p>
<ul>
<li>分段帧的首帧为 fin == false，frameType == TextWebFrame 或 BinaryWebFrame中间帧 fin == false，frameType == ContinuationWebFrame尾帧 fin == true， frameType == ContinuationWebFrame；</li>
<li>非分段帧为     fin == true， frameType != ContinuationWebFrame。</li>
</ul>
<blockquote>
<p><strong>注意：</strong></p>
<ul>
<li>数据帧（Text，Binary）可以分段，用户需要多次调用 read 将所有分段帧读完（以下称为接收到完整的 message），再将分段帧的 payload 按接收序拼接Text 帧的 payload 为 UTF-8 编码，用户在接收到完整的 message 后，调用 String.fromUtf8函数将拼接后的 payload 转成字符串Binary 帧的 payload 的意义由使用其的应用确定，用户在接收到完整的 message 后，将拼接后的 payload 传给上层应用；</li>
<li>控制帧（Close，Ping，Pong）不可分段；</li>
<li>控制帧本身不可分段，但其可以穿插在分段的数据帧之间。分段的数据帧之间不可出现其他数据帧，如果用户收到穿插的分段数据帧，则需要当作错误处理；</li>
<li>客户端收到 masked 帧，服务器收到 unmasked 帧，断开底层连接并抛出异常；</li>
<li>rsv1、rsv2、rsv3 位被设置（暂不支持 extensions，因此 rsv 位必须为 0），断开底层连接并抛出异常；</li>
<li>收到无法理解的帧类型（只支持 Continuation，Text，Binary，Close，Ping，Pong），断开底层连接并抛出异常；</li>
<li>收到分段或 payload 长度大于 125 bytes 的控制帧（Close，Ping，Pong），断开底层连接并抛出异常；</li>
<li>收到 payload 长度大于 20M 的帧，断开底层连接并抛出异常；</li>
<li>closeConn 关闭连接后继续调用读，抛出异常。</li>
</ul>
</blockquote>
<p>返回值：</p>
<ul>
<li><a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> - 读到的 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 对象。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 底层连接错误。</li>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 收到不符合协议规定的帧，此时会给对端发送 Close 帧说明错误信息，并断开底层连接。</li>
<li><a href="http_package_exceptions.html#class-connectionexception">ConnectionException</a> - 从连接中读数据时对端已关闭连接抛此异常。</li>
</ul>
<h3 id="func-writewebsocketframetype-arrayuint8-int64"><a class="header" href="#func-writewebsocketframetype-arrayuint8-int64">func write(WebSocketFrameType, Array&lt;UInt8&gt;, Int64)</a></h3>
<pre><code class="language-cangjie">public func write(frameType: WebSocketFrameType, byteArray: Array&lt;UInt8&gt;, frameSize!: Int64 = FRAMESIZE): Unit
</code></pre>
<p>功能：发送数据，非线程安全（即对同一个 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象不支持多线程写）。</p>
<blockquote>
<p><strong>注意：</strong></p>
<p>write 函数将数据以 <a href="http_package_classes.html#class-websocket">WebSocket</a> 帧的形式发送给对端；</p>
<ul>
<li>如果发送数据帧（Text，Binary），传入的 byteArray 如果大于 frameSize (默认 4 * 1024 bytes)，我们会将其分成小于等于 frameSize 的 payload 以分段帧的形式发送，否则不分段；</li>
<li>如果发送控制帧（Close，Ping，Pong），传入的 byteArray 的大小需要小于等于 125 bytes，Close 帧的前两个字节为状态码，可用的状态码见 RFC 6455 7.4. Status Codes协议规定，Close 帧发送之后，禁止再发送数据帧，如果发送则会抛出异常；</li>
<li>用户需要自己保证其传入的 byteArray 符合协议，如 Text 帧的 payload 需要是 UTF-8 编码，如果数据帧设置了 frameSize，那么需要大于 0，否则抛出异常；</li>
<li>发送数据帧时，frameSize 小于等于 0，抛出异常；</li>
<li>用户发送控制帧时，传入的数据大于 125 bytes，抛出异常；</li>
<li>用户传入非 Text，Binary，Close，Ping，Pong 类型的帧类型，抛出异常；</li>
<li>发送 Close 帧时传入非法的状态码，或 reason 数据超过 123 bytes，抛出异常；</li>
<li>发送完 Close 帧后继续发送数据帧，抛出异常；</li>
<li>closeConn 关闭连接后调用写，抛出异常。</li>
</ul>
</blockquote>
<p>参数：</p>
<ul>
<li>frameType: <a href="http_package_enums.html#enum-websocketframetype">WebSocketFrameType</a> - 所需发送的帧的类型。</li>
<li>byteArray: Array&lt;UInt8&gt; - 所需发送的帧的 payload（二进制形式）。</li>
<li>frameSize!: Int64 - 分段帧的大小，默认为 4 * 1024 bytes，frameSize 不会对控制帧生效（控制帧设置了无效）。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 底层连接错误时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 传入非法的帧类型，或者数据时抛出异常。</li>
</ul>
<h3 id="func-writecloseframeuint16-string"><a class="header" href="#func-writecloseframeuint16-string">func writeCloseFrame(?UInt16, String)</a></h3>
<pre><code class="language-cangjie">public func writeCloseFrame(status!: ?UInt16 = None, reason!: String = &quot;&quot;): Unit
</code></pre>
<p>功能：发送 Close 帧。</p>
<blockquote>
<p><strong>注意：</strong></p>
<p>协议规定，Close 帧发送之后，禁止再发送数据帧。如果用户不设置 status，那么 reason 不会被发送（即有 reason 必有 status）；控制帧的 payload 不超过 125 bytes，Close 帧的前两个 bytes 为 status，因此 reason 不能超过 123 bytes，closeConn 关闭连接后调用写，抛出异常。</p>
</blockquote>
<p>参数：</p>
<ul>
<li>status!: ?UInt16 - 发送的 Close 帧的状态码，默认为 None，表示不发送状态码和 reason。</li>
<li>reason!: String - 关闭连接的说明，默认为空字符串，发送时会转成 UTF-8，不保证可读，debug 用。</li>
</ul>
<p>异常：</p>
<ul>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 传入非法的状态码，或 reason 数据超过 123 bytes时抛出异常。</li>
</ul>
<h3 id="func-writepingframearrayuint8"><a class="header" href="#func-writepingframearrayuint8">func writePingFrame(Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func writePingFrame(byteArray: Array&lt;UInt8&gt;): Unit
</code></pre>
<p>功能：提供发送 Ping 帧的快捷函数，closeConn 关闭连接后调用写，抛出异常。</p>
<p>参数：</p>
<ul>
<li>byteArray: Array&lt;UInt8&gt; - 所需发送的帧的 payload（二进制形式）。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 底层连接错误时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 传入的数据大于 125 bytes，抛出异常。</li>
</ul>
<h3 id="func-writepongframearrayuint8"><a class="header" href="#func-writepongframearrayuint8">func writePongFrame(Array&lt;UInt8&gt;)</a></h3>
<pre><code class="language-cangjie">public func writePongFrame(byteArray: Array&lt;UInt8&gt;): Unit
</code></pre>
<p>功能：提供发送 Pong 帧的快捷函数，closeConn 关闭连接后调用写，抛出异常。</p>
<p>参数：</p>
<ul>
<li>byteArray: Array&lt;UInt8&gt; - 所需发送的帧的 payload（二进制形式）。</li>
</ul>
<p>异常：</p>
<ul>
<li>SocketException - 底层连接错误时抛出异常。</li>
<li><a href="http_package_exceptions.html#class-websocketexception">WebSocketException</a> - 传入的数据大于 125 bytes，抛出异常。</li>
</ul>
<h2 id="class-websocketframe"><a class="header" href="#class-websocketframe">class WebSocketFrame</a></h2>
<pre><code class="language-cangjie">public class WebSocketFrame
</code></pre>
<p>功能：<a href="http_package_classes.html#class-websocket">WebSocket</a> 用于读的基本单元。</p>
<p><a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 提供了三个属性，其中 fin 和 frameType 共同说明了帧是否分段和帧的类型。payload 为帧的载荷。</p>
<ul>
<li>分段帧的首帧为 fin == false，frameType == TextWebFrame 或 BinaryWebFrame；</li>
<li>中间帧 fin == false，frameType == ContinuationWebFrame；</li>
<li>尾帧 fin == true， frameType == ContinuationWebFrame；</li>
<li>非分段帧为     fin == true， frameType != ContinuationWebFrame；</li>
<li>用户仅能通过 <a href="http_package_classes.html#class-websocket">WebSocket</a> 对象的 read 函数得到 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a>。数据帧可分段，如果用户收到分段帧，则需要多次调用 read 函数直到收到完整的 message，并将所有分段的 payload 按接收顺序拼接。</li>
</ul>
<blockquote>
<p><strong>注意：</strong></p>
<p>由于控制帧可以穿插在分段帧之间，用户在拼接分段帧的 payload 时需要单独处理控制帧。分段帧之间仅可穿插控制帧，如果用户在分段帧之间接收到其他数据帧，则需要当作错误处理。</p>
</blockquote>
<h3 id="prop-fin"><a class="header" href="#prop-fin">prop fin</a></h3>
<pre><code class="language-cangjie">public prop fin: Bool
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 的 fin 属性，fin 与 frameType 共同说明了帧是否分段和帧的类型。</p>
<p>类型：Bool</p>
<h3 id="prop-frametype"><a class="header" href="#prop-frametype">prop frameType</a></h3>
<pre><code class="language-cangjie">public prop frameType: WebSocketFrameType
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 的帧类型，fin 与 frameType 共同说明了帧是否分段和帧的类型。</p>
<p>类型：<a href="http_package_enums.html#enum-websocketframetype">WebSocketFrameType</a></p>
<h3 id="prop-payload"><a class="header" href="#prop-payload">prop payload</a></h3>
<pre><code class="language-cangjie">public prop payload: Array&lt;UInt8&gt;
</code></pre>
<p>功能：获取 <a href="http_package_classes.html#class-websocketframe">WebSocketFrame</a> 的帧载荷。如果是分段数据帧，用户需要在接收到完整的 message 后，将所有分段的 payload 按接收序拼接。</p>
<p>类型：Array&lt;UInt8&gt;</p>

                    </main>

                    <nav class="nav-wrapper" aria-label="Page navigation">
                        <!-- Mobile navigation buttons -->
                            <a rel="prev" href="../../../net/http/http_package_api/http_package_interfaces.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                                <i class="fa fa-angle-left"></i>
                            </a>

                            <a rel="next prefetch" href="../../../net/http/http_package_api/http_package_enums.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                                <i class="fa fa-angle-right"></i>
                            </a>

                        <div style="clear: both"></div>
                    </nav>
                </div>
            </div>

            <nav class="nav-wide-wrapper" aria-label="Page navigation">
                    <a rel="prev" href="../../../net/http/http_package_api/http_package_interfaces.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
                        <i class="fa fa-angle-left"></i>
                    </a>

                    <a rel="next prefetch" href="../../../net/http/http_package_api/http_package_enums.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
                        <i class="fa fa-angle-right"></i>
                    </a>
            </nav>

        </div>




        <script>
            window.playground_copyable = true;
        </script>


        <script src="../../../elasticlunr.min.js"></script>
        <script src="../../../mark.min.js"></script>
        <script src="../../../searcher.js"></script>

        <script src="../../../clipboard.min.js"></script>
        <script src="../../../cangjie-highlight-export.js"></script><script src="../../../highlight.js"></script>
        <script src="../../../book.js"></script>

        <!-- Custom JS scripts -->
        
        <script src="../../../cangjie-highlight-export.js"></script><script src="../../../highlight.js"></script>
        <script src="../../../assets/elasticlunr.js"></script>
        <script src="../../../assets/fzf.umd.js"></script>
        <script src="../../../assets/sidebar.js"></script>


    </div>
    </body>
</html>
